Resolve merge conflict introduced with recent changes to master.

This commit is contained in:
Daniel Roschka 2015-05-30 18:17:29 +02:00
commit 2ffd7c4b39
12 changed files with 109 additions and 93 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@
*.conf *.conf
*~ *~
/binder/secret.txt /binder/secret.txt
/binder/local_settings.py

12
.travis.yml Normal file
View File

@ -0,0 +1,12 @@
language: python
python:
- "2.7"
env:
- DJANGO="Django>=1.6,<1.7"
- DJANGO="Django>=1.7,<1.8"
- DJANGO="Django>=1.8,<1.9"
install:
- pip install -q $DJANGO
- pip install -r requirements.txt
script:
- python manage.py test

View File

@ -1,5 +1,7 @@
# Binder # # Binder #
[![Build Status](https://travis-ci.org/jforman/binder.svg?branch=master)](https://travis-ci.org/jforman/binder)
A Django web application for viewing and editing BIND DNS zone records. A Django web application for viewing and editing BIND DNS zone records.
Binder supports adding and deleting DNS records (and eventually editing in place). TSIG-authenticated transfers and updates are supported. Binder supports adding and deleting DNS records (and eventually editing in place). TSIG-authenticated transfers and updates are supported.

View File

@ -2,11 +2,11 @@
# 3rd Party # 3rd Party
from django import forms from django import forms
from django.conf import settings
from django.forms import ValidationError from django.forms import ValidationError
# App Imports # App Imports
from models import Key from models import Key
import local_settings
### Custom Form Fields ### Custom Form Fields
@ -40,10 +40,10 @@ class FormAddForwardRecord(forms.Form):
""" Form used to add a Forward DNS record. """ """ Form used to add a Forward DNS record. """
dns_server = forms.CharField(max_length=100) dns_server = forms.CharField(max_length=100)
record_name = forms.RegexField(max_length=100, regex="^[a-zA-Z0-9-_]+$", required=False) record_name = forms.RegexField(max_length=100, regex="^[a-zA-Z0-9-_]+$", required=False)
record_type = forms.ChoiceField(choices=local_settings.RECORD_TYPE_CHOICES) record_type = forms.ChoiceField(choices=settings.RECORD_TYPE_CHOICES)
zone_name = forms.CharField(max_length=100) zone_name = forms.CharField(max_length=100)
record_data = forms.GenericIPAddressField() record_data = forms.GenericIPAddressField()
ttl = forms.ChoiceField(choices=local_settings.TTL_CHOICES) ttl = forms.ChoiceField(choices=settings.TTL_CHOICES)
create_reverse = forms.BooleanField(required=False) create_reverse = forms.BooleanField(required=False)
key_name = forms.ModelChoiceField(queryset=Key.objects.all(), required=False) key_name = forms.ModelChoiceField(queryset=Key.objects.all(), required=False)
@ -54,7 +54,7 @@ class FormAddReverseRecord(forms.Form):
record_type = forms.RegexField(regex=r"^PTR$",error_messages={"invalid" : "The only valid choice here is PTR."}) record_type = forms.RegexField(regex=r"^PTR$",error_messages={"invalid" : "The only valid choice here is PTR."})
zone_name = forms.CharField(max_length=100) zone_name = forms.CharField(max_length=100)
record_data = CustomStringPeriodSuffix(required=True) record_data = CustomStringPeriodSuffix(required=True)
ttl = forms.ChoiceField(choices=local_settings.TTL_CHOICES) ttl = forms.ChoiceField(choices=settings.TTL_CHOICES)
key_name = forms.ModelChoiceField(queryset=Key.objects.all(), required=False) key_name = forms.ModelChoiceField(queryset=Key.objects.all(), required=False)
create_reverse = forms.BooleanField(required=False) create_reverse = forms.BooleanField(required=False)
@ -64,7 +64,7 @@ class FormAddCnameRecord(forms.Form):
originating_record = forms.CharField(max_length=100) originating_record = forms.CharField(max_length=100)
cname = forms.RegexField(max_length=100, regex="^[a-zA-Z0-9-_]+$") cname = forms.RegexField(max_length=100, regex="^[a-zA-Z0-9-_]+$")
zone_name = forms.CharField(max_length=256) zone_name = forms.CharField(max_length=256)
ttl = forms.ChoiceField(choices=local_settings.TTL_CHOICES) ttl = forms.ChoiceField(choices=settings.TTL_CHOICES)
key_name = forms.ModelChoiceField(queryset=Key.objects.all(), required=False) key_name = forms.ModelChoiceField(queryset=Key.objects.all(), required=False)
class FormDeleteRecord(forms.Form): class FormDeleteRecord(forms.Form):

View File

@ -1,10 +0,0 @@
### Local settings to be shared across modules.
TTL_CHOICES = ((300, "5 minutes"),
(1800, "30 minutes"),
(3600, "1 hour"),
(43200, "12 hours"),
(86400, "1 day"))
RECORD_TYPE_CHOICES = (("A", "A"),
("AAAA", "AAAA"))

View File

@ -88,4 +88,18 @@ INSTALLED_APPS = (
TEST_RUNNER = 'django.test.runner.DiscoverRunner' TEST_RUNNER = 'django.test.runner.DiscoverRunner'
TTL_CHOICES = ((300, "5 minutes"),
(1800, "30 minutes"),
(3600, "1 hour"),
(43200, "12 hours"),
(86400, "1 day"))
RECORD_TYPE_CHOICES = (("A", "A"),
("AAAA", "AAAA"))
LOGIN_REDIRECT_URL = '/' LOGIN_REDIRECT_URL = '/'
try:
from local_settings import *
except ImportError:
pass

View File

@ -3,7 +3,9 @@
{% block header %} {% block header %}
<head> <head>
<title>Binder DNS Admin</title> <title>Binder DNS Admin</title>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}bootstrap/css/bootstrap.css" /> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}bootstrap/css/bootstrap.min.css" />
<script src="{{ STATIC_URL }}sorttable.js"></script> <script src="{{ STATIC_URL }}sorttable.js"></script>
</head> </head>
{% endblock header %} {% endblock header %}
@ -30,7 +32,7 @@
<div class="col-md-10"> <div class="col-md-10">
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
{% block pageheader %}{% endblock pageheader %} {% block pageheader %}{% endblock pageheader %}
</div> </div>
</div> </div>

View File

@ -6,37 +6,37 @@
<form class="form-horizontal" action="/add_cname_record/result/" method="post">{% csrf_token %} <form class="form-horizontal" action="/add_cname_record/result/" method="post">{% csrf_token %}
<legend>Create CNAME record</legend> <legend>Create CNAME record</legend>
<div class="form-group"> <div class="form-group">
<label class="control-label col-md-2">DNS Server</label> <label for="id_dns_server" class="control-label col-md-2">DNS Server</label>
<div class="controls col-md-10"> <div class="controls col-md-10">
<input type="text" class="form-control" name="dns_server" value="{{dns_server.hostname}}" readonly /> <input type="text" id="id_dns_server" class="form-control" name="dns_server" value="{{dns_server.hostname}}" readonly />
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label col-md-2">Zone</label> <label for="id_zone_name" class="control-label col-md-2">Zone</label>
<div class="controls col-md-10"> <div class="controls col-md-10">
<input type="text" class="form-control" name="zone_name" value="{{zone_name}}" readonly /> <input type="text" id="id_zone_name" class="form-control" name="zone_name" value="{{zone_name}}" readonly />
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label col-md-2">Originating Record</label> <label for="id_originating_record" class="control-label col-md-2">Originating Record</label>
<div class="controls col-md-10"> <div class="controls col-md-10">
<input type="text" class="form-control" name="originating_record" value="{{originating_record}}" readonly /> <input type="text" id="id_originating_record" class="form-control" name="originating_record" value="{{originating_record}}" readonly />
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label col-md-2">CNAME</label> <label for="id_cname" class="control-label col-md-2">CNAME</label>
<div class="controls col-md-10"> <div class="controls col-md-10">
{% if form_errors.cname %} {% if form_errors.cname %}
<div class="alert alert-danger" role="alert"> <div class="alert alert-danger" role="alert">
Error in CNAME input: {{ form_errors.cname|stringformat:"s"|striptags }} Previous Value: {{ form_data.cname }} Error in CNAME input: {{ form_errors.cname|stringformat:"s"|striptags }} Previous Value: {{ form_data.cname }}
</div> </div>
{% endif %} {% endif %}
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control" name="cname"/> <input type="text" id="id_originating_record" class="form-control" name="cname"/>
<div class="input-group-addon">.{{zone_name}}</div> <div class="input-group-addon">.{{zone_name}}</div>
</div> </div>
</div> </div>
</div> </div>
@ -45,17 +45,17 @@
<label class="control-label col-md-2">TTL</label> <label class="control-label col-md-2">TTL</label>
<div class="controls col-md-10"> <div class="controls col-md-10">
{% for ttl, description in ttl_choices %} {% for ttl, description in ttl_choices %}
<label class="radio-inline"> <label for="id_ttl_{{ttl}}" class="radio-inline">
<input type="radio" name="ttl" id="ttl_{{ttl}}" value="{{ttl}}">{{ttl}} ({{description}}) <input type="radio" id="id_ttl_{{ ttl }}" name="ttl" value="{{ttl}}">{{ttl}} ({{description}})
</label> </label>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label col-md-2">TSIG Key</label> <label for="id_key_name" class="control-label col-md-2">TSIG Key</label>
<div class="controls col-md-10"> <div class="controls col-md-10">
<select class="form-control" name="key_name"> <select id="id_key_name" class="form-control" name="key_name">
{% for key in tsig_keys %} {% for key in tsig_keys %}
<option value="{{key.id}}"{% if key == dns_server.default_transfer_key %} selected="selected"{% endif %}>{{key}}</option> <option value="{{key.id}}"{% if key == dns_server.default_transfer_key %} selected="selected"{% endif %}>{{key}}</option>
{% empty %} {% empty %}
@ -64,8 +64,7 @@
</select> </select>
</div> </div>
</div> </div>
<button type="submit" class="btn btn-default">Save Changes</button>
<button type="submit" class="btn">Save Changes</button>
<a href="{% url "zone_list" dns_server=dns_server zone_name=zone_name %}" class="btn btn-warning">Cancel</a> <a href="{% url "zone_list" dns_server=dns_server zone_name=zone_name %}" class="btn btn-warning">Cancel</a>
</form> </form>

View File

@ -6,22 +6,22 @@
<form class="form-horizontal" action="/add_record/result/" method="POST">{% csrf_token %} <form class="form-horizontal" action="/add_record/result/" method="POST">{% csrf_token %}
<legend>Create Record</legend> <legend>Create Record</legend>
<div class="form-group"> <div class="form-group">
<label class="control-label col-md-2">DNS Server</label> <label for="id_dns_server" class="control-label col-md-2">DNS Server</label>
<div class="controls col-md-10"> <div class="controls col-md-10">
<input type="text" class="form-control" name="dns_server" value="{{dns_server.hostname}}" readonly /> <input type="text" id="id_dns_server" class="form-control" name="dns_server" value="{{dns_server.hostname}}" readonly />
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label col-md-2">Zone</label> <label for="id_zone_name" class="control-label col-md-2">Zone</label>
<div class="controls col-md-10"> <div class="controls col-md-10">
<input type="text" class="form-control" name="zone_name" value="{{zone_name}}" readonly> <input type="text" id="id_zone_name" class="form-control" name="zone_name" value="{{zone_name}}" readonly>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label col-md-2">Record Name</label> <label for="id_record_name" class="control-label col-md-2">Record Name</label>
<div class="controls col-md-10"> <div class="controls col-md-10">
{% if form_errors.record_name %} {% if form_errors.record_name %}
<div class="alert alert-danger" role="alert"> <div class="alert alert-danger" role="alert">
@ -29,8 +29,8 @@
</div> </div>
{% endif %} {% endif %}
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control" name="record_name"/> <input type="text" id="id_record_name" class="form-control" name="record_name"/>
<div class="input-group-addon">.{{zone_name}}</div> <div class="input-group-addon">.{{zone_name}}</div>
</div> </div>
</div> </div>
</div> </div>
@ -40,34 +40,34 @@
<div class="controls col-md-10"> <div class="controls col-md-10">
{% if "in-addr.arpa" not in zone_name and "ip6.arpa" not in zone_name %} {% if "in-addr.arpa" not in zone_name and "ip6.arpa" not in zone_name %}
{% for type, name in record_type_choices %} {% for type, name in record_type_choices %}
<label class="radio-inline"> <label for="id_record_type_{{ name }}" class="radio-inline">
<input type="radio" name="record_type" id="record_type_{{name}}" value="{{name}}">{{name}} <input type="radio" id="id_record_type_{{ name }}" name="record_type" value="{{name}}">{{name}}
</label> </label>
{% endfor %} {% endfor %}
{% else %} {% else %}
<label class="radio-inline"> <label for="id_record_type" class="radio-inline">
<input type="radio" name="record_type" id="record_type_PTR" value="PTR" checked="checked">PTR <input type="radio" id="id_record_type" name="record_type" id="record_type_PTR" value="PTR" checked="checked">PTR
</label> </label>
{% endif %} {% endif %}
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label col-md-2">Record Data</label> <label for="id_record_data" class="control-label col-md-2">Record Data</label>
<div class="controls col-md-10"> <div class="controls col-md-10">
{% if form_errors.record_data %} {% if form_errors.record_data %}
<div class="alert alert-danger" role="alert"> <div class="alert alert-danger" role="alert">
Record Data: {{ form_errors.record_data|stringformat:"s"|striptags }} Previous Value: {{ form_data.record_data }} Record Data: {{ form_errors.record_data|stringformat:"s"|striptags }} Previous Value: {{ form_data.record_data }}
</div> </div>
{% endif %} {% endif %}
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control" name="record_data"/> <input type="text" id="id_record_data" class="form-control" name="record_data"/>
{% if "in-addr.arpa" not in zone_name and "ip6.arpa" not in zone_name %} {% if "in-addr.arpa" not in zone_name and "ip6.arpa" not in zone_name %}
<div class="input-group-addon">IP Address</div> <div class="input-group-addon">IP Address</div>
{% else %} {% else %}
<div class="input-group-addon">FQDN</div> <div class="input-group-addon">FQDN</div>
{% endif %} {% endif %}
</div> </div>
</div> </div>
</div> </div>
@ -75,28 +75,28 @@
<label class="control-label col-md-2">TTL</label> <label class="control-label col-md-2">TTL</label>
<div class="controls col-md-10"> <div class="controls col-md-10">
{% for ttl, description in ttl_choices %} {% for ttl, description in ttl_choices %}
<label class="radio-inline"> <label for="id_ttl_{{ ttl }}" class="radio-inline">
<input type="radio" name="ttl" id="ttl_{{ttl}}" value="{{ttl}}">{{ttl}} ({{description}}) <input type="radio" id="id_ttl_{{ ttl }}" name="ttl" value="{{ttl}}">{{ttl}} ({{description}})
</label> </label>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
{% if "in-addr.arpa" not in zone_name and "ip.arpa" not in zone_name %} {% if "in-addr.arpa" not in zone_name and "ip.arpa" not in zone_name %}
<div class="form-group"> <div class="form-group">
<label class="control-label col-md-2">Create PTR?</label> <label for="id_create_reverse" class="control-label col-md-2">Create PTR?</label>
<div class="checkbox controls col-md-10"> <div class="checkbox controls col-md-10">
<label> <label>
<input type="checkbox" name="create_reverse" id="create_reverse" value="True" aria-label="create ptr record?">Yes <input type="checkbox" id="id_create_reverse" name="create_reverse" id="create_reverse" value="True" aria-label="create ptr record?">Yes
</label> <label>
</div> </div>
</div> </div>
{% endif %} {% endif %}
<div class="form-group"> <div class="form-group">
<label class="control-label col-md-2">TSIG Key</label> <label for="id_key_name" class="control-label col-md-2">TSIG Key</label>
<div class="controls col-md-10"> <div class="controls col-md-10">
<select class="form-control" name="key_name"> <select id="id_key_name" class="form-control" name="key_name">
{% for key in tsig_keys %} {% for key in tsig_keys %}
<option value="{{key.id}}"{% if key == dns_server.default_transfer_key %} selected="selected"{% endif %}>{{key}}</option> <option value="{{key.id}}"{% if key == dns_server.default_transfer_key %} selected="selected"{% endif %}>{{key}}</option>
{% empty %} {% empty %}
@ -106,7 +106,7 @@
</div> </div>
</div> </div>
<button type="submit" class="btn">Save Changes</button> <button type="submit" class="btn btn-default">Save Changes</button>
<a href="{% url "zone_list" dns_server=dns_server zone_name=zone_name %}" class="btn btn-warning">Cancel</a> <a href="{% url "zone_list" dns_server=dns_server zone_name=zone_name %}" class="btn btn-warning">Cancel</a>
</form> </form>
{% endblock body %} {% endblock body %}

View File

@ -22,24 +22,24 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<td>TSIG Key</td> <td><label for="id_key_name">TSIG Key</label></td>
<td> <td>
<div class="form-group"> <div class="form-group">
<div class="controls"> <div class="controls">
<select class="form-control" name="key_name"> <select id="id_key_name" class="form-control" name="key_name">
{% for key in tsig_keys %} {% for key in tsig_keys %}
<option value="{{key.id}}"{% if key == dns_server.default_transfer_key %} selected="selected"{% endif %}>{{key}}</option> <option value="{{key.id}}"{% if key == dns_server.default_transfer_key %} selected="selected"{% endif %}>{{key}}</option>
{% empty %} {% empty %}
<option selected="selected" value=""/> <option selected="selected" value=""/>
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
</div> </div>
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <td>
<button type="submit" class="btn">Yes, really delete.</button> <button type="submit" class="btn btn-default">Yes, really delete.</button>
<a href="{% url "zone_list" dns_server=dns_server zone_name=zone_name %}" class="btn btn-warning">Cancel</a> <a href="{% url "zone_list" dns_server=dns_server zone_name=zone_name %}" class="btn btn-warning">Cancel</a>
</td> </td>
<td></td> <td></td>

View File

@ -4,10 +4,14 @@
{% block body %} {% block body %}
{% if not errors %} {% if not errors %}
<form action="{% url "delete_record" %}" method="post">{% csrf_token %} <a href="{% url "add_record" dns_server=dns_server zone_name=zone_name %}" class="btn btn-default">Add Record</a>
<table class="table table-condensed table-hover sortable">
<a href="{% url "add_record" dns_server=dns_server zone_name=zone_name %}" class="btn btn-default">Add Record</a></button>
<form action="{% url "delete_record" %}" method="post">{% csrf_token %}
<input type="hidden" name="dns_server" value="{{ dns_server.hostname }}">
<input type="hidden" name="zone_name" value="{{ zone_name }}">
<table class="table table-condensed table-hover sortable">
<tr> <tr>
<th>Select</th> <th>Select</th>
<th>Name</th> <th>Name</th>
@ -18,17 +22,9 @@
<th></th> <th></th>
</tr> </tr>
<input type="hidden" name="dns_server" value="{{ dns_server.hostname }}">
<input type="hidden" name="zone_name" value="{{ zone_name }}">
{% for current_record in zone_array %} {% for current_record in zone_array %}
<tr> <tr>
<td> <td><input type="checkbox" id="rr_{{current_record.rr_name}}" name="rr_list" value="{{ current_record.rr_name }}.{{ zone_name }}" /></td>
<div class="checkbox">
<label>
<input type="checkbox" id="rr_{{current_record.rr_name}}" name="rr_list" value="{{ current_record.rr_name }}.{{ zone_name }}"/>
</label>
</div>
</td>
<td>{{ current_record.rr_name }}</td> <td>{{ current_record.rr_name }}</td>
<td>{{ current_record.rr_ttl }}</td> <td>{{ current_record.rr_ttl }}</td>
<td>{{ current_record.rr_class }}</td> <td>{{ current_record.rr_class }}</td>
@ -37,7 +33,7 @@
<td> <td>
<div class="btn-toolbar" style="margin: 0;"> <div class="btn-toolbar" style="margin: 0;">
<div class="btn-group"> <div class="btn-group">
<button class="btn dropdown-toggle" data-toggle="dropdown">Record Actions <span class="caret"></span></button> <button class="btn btn-default dropdown-toggle" data-toggle="dropdown">Record Actions <span class="caret"></span></button>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a href="#">Edit Record (Coming Soon)</a></li> <li><a href="#">Edit Record (Coming Soon)</a></li>
{% if current_record.rr_type == "A" %} {% if current_record.rr_type == "A" %}

View File

@ -1,11 +1,11 @@
### Binder VIews ### Binder VIews
# 3rd Party # 3rd Party
from django.conf import settings
from django.shortcuts import get_object_or_404, redirect, render from django.shortcuts import get_object_or_404, redirect, render
# App Imports # App Imports
from binder import exceptions, forms, helpers, models from binder import exceptions, forms, helpers, models
import local_settings
def home_index(request): def home_index(request):
""" List the main index page for Binder. """ """ List the main index page for Binder. """
@ -71,8 +71,8 @@ def view_add_record(request, dns_server, zone_name):
{ "dns_server" : this_server, { "dns_server" : this_server,
"zone_name" : zone_name, "zone_name" : zone_name,
"tsig_keys" : models.Key.objects.all(), "tsig_keys" : models.Key.objects.all(),
"ttl_choices" : local_settings.TTL_CHOICES, "ttl_choices": settings.TTL_CHOICES,
"record_type_choices" : local_settings.RECORD_TYPE_CHOICES, "record_type_choices": settings.RECORD_TYPE_CHOICES,
}) })
@ -117,8 +117,8 @@ def view_add_record_result(request):
{ "dns_server" : dns_server, { "dns_server" : dns_server,
"zone_name" : request.POST["zone_name"], "zone_name" : request.POST["zone_name"],
"tsig_keys" : models.Key.objects.all(), "tsig_keys" : models.Key.objects.all(),
"ttl_choices" : local_settings.TTL_CHOICES, "ttl_choices": settings.TTL_CHOICES,
"record_type_choices" : local_settings.RECORD_TYPE_CHOICES, "record_type_choices": settings.RECORD_TYPE_CHOICES,
"form_errors" : form.errors, "form_errors" : form.errors,
"form_data" : request.POST }) "form_data" : request.POST })
@ -132,7 +132,7 @@ def view_add_cname_record(request, dns_server, zone_name, record_name):
{ "dns_server" : this_server, { "dns_server" : this_server,
"originating_record" : "%s.%s" % (record_name, zone_name), "originating_record" : "%s.%s" % (record_name, zone_name),
"zone_name" : zone_name, "zone_name" : zone_name,
"ttl_choices" : local_settings.TTL_CHOICES, "ttl_choices": settings.TTL_CHOICES,
"tsig_keys" : models.Key.objects.all() }) "tsig_keys" : models.Key.objects.all() })
@ -170,7 +170,7 @@ def view_add_cname_result(request):
"originating_record" : request.POST["originating_record"], "originating_record" : request.POST["originating_record"],
"form_data" : request.POST, "form_data" : request.POST,
"form_errors" : form.errors, "form_errors" : form.errors,
"ttl_choices" : local_settings.TTL_CHOICES, "ttl_choices": settings.TTL_CHOICES,
"tsig_keys" : models.Key.objects.all() }) "tsig_keys" : models.Key.objects.all() })