Merge branch 'refactored-views' of https://github.com/Dunedan/binder into Dunedan-refactored-views
This commit is contained in:
commit
ab9b28d525
|
@ -17,7 +17,7 @@ class ZoneException(Exception):
|
||||||
|
|
||||||
class RecordException(Exception):
|
class RecordException(Exception):
|
||||||
|
|
||||||
"""Thrown when there is an issue dealign with a Record.
|
"""Thrown when there is an issue dealing with a Record.
|
||||||
|
|
||||||
* Adding or deleting.
|
* Adding or deleting.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -17,7 +17,8 @@ class CustomUnicodeListField(forms.CharField):
|
||||||
try:
|
try:
|
||||||
string_list = [str(cur_rr) for cur_rr in eval(value)]
|
string_list = [str(cur_rr) for cur_rr in eval(value)]
|
||||||
except:
|
except:
|
||||||
raise ValidationError("Error in converting Unicode list to list of Strings: %r" % value)
|
raise ValidationError("Error in converting Unicode list to list "
|
||||||
|
"of strings: %r" % value)
|
||||||
return string_list
|
return string_list
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,7 +38,8 @@ class CustomStringPeriodSuffix(forms.CharField):
|
||||||
if new_string[-1] != ".":
|
if new_string[-1] != ".":
|
||||||
new_string += "."
|
new_string += "."
|
||||||
except:
|
except:
|
||||||
raise ValidationError("Unable to stick a period on the end of your input: %r" % value)
|
raise ValidationError("Unable to stick a period on the end of "
|
||||||
|
"your input: %r" % value)
|
||||||
|
|
||||||
return new_string
|
return new_string
|
||||||
|
|
||||||
|
@ -50,13 +52,17 @@ class FormAddForwardRecord(forms.Form):
|
||||||
record_name = forms.RegexField(max_length=100,
|
record_name = forms.RegexField(max_length=100,
|
||||||
regex="^[a-zA-Z0-9-_]+$",
|
regex="^[a-zA-Z0-9-_]+$",
|
||||||
required=False)
|
required=False)
|
||||||
record_type = forms.ChoiceField(choices=settings.RECORD_TYPE_CHOICES)
|
record_type = forms.ChoiceField(choices=settings.RECORD_TYPE_CHOICES,
|
||||||
|
widget=forms.RadioSelect)
|
||||||
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=settings.TTL_CHOICES)
|
ttl = forms.ChoiceField(choices=settings.TTL_CHOICES,
|
||||||
|
widget=forms.RadioSelect)
|
||||||
create_reverse = forms.BooleanField(required=False)
|
create_reverse = forms.BooleanField(required=False)
|
||||||
key_name = forms.ModelChoiceField(queryset=Key.objects.all(),
|
key_name = forms.ModelChoiceField(queryset=Key.objects.all(),
|
||||||
required=False)
|
required=False,
|
||||||
|
widget=forms.RadioSelect,
|
||||||
|
empty_label=None)
|
||||||
|
|
||||||
|
|
||||||
class FormAddReverseRecord(forms.Form):
|
class FormAddReverseRecord(forms.Form):
|
||||||
|
@ -66,12 +72,16 @@ class FormAddReverseRecord(forms.Form):
|
||||||
dns_server = forms.CharField(max_length=100)
|
dns_server = forms.CharField(max_length=100)
|
||||||
record_name = forms.IntegerField(min_value=0, max_value=255)
|
record_name = forms.IntegerField(min_value=0, max_value=255)
|
||||||
record_type = forms.RegexField(regex=r"^PTR$",
|
record_type = forms.RegexField(regex=r"^PTR$",
|
||||||
error_messages={"invalid": "The only valid choice here is 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=settings.TTL_CHOICES)
|
ttl = forms.ChoiceField(choices=settings.TTL_CHOICES)
|
||||||
key_name = forms.ModelChoiceField(queryset=Key.objects.all(),
|
key_name = forms.ModelChoiceField(queryset=Key.objects.all(),
|
||||||
required=False)
|
required=False,
|
||||||
|
widget=forms.RadioSelect,
|
||||||
|
empty_label=None)
|
||||||
create_reverse = forms.BooleanField(required=False)
|
create_reverse = forms.BooleanField(required=False)
|
||||||
|
|
||||||
|
|
||||||
|
@ -83,9 +93,12 @@ 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=settings.TTL_CHOICES)
|
ttl = forms.ChoiceField(choices=settings.TTL_CHOICES,
|
||||||
|
widget=forms.RadioSelect)
|
||||||
key_name = forms.ModelChoiceField(queryset=Key.objects.all(),
|
key_name = forms.ModelChoiceField(queryset=Key.objects.all(),
|
||||||
required=False)
|
required=False,
|
||||||
|
widget=forms.RadioSelect,
|
||||||
|
empty_label=None)
|
||||||
|
|
||||||
|
|
||||||
class FormDeleteRecord(forms.Form):
|
class FormDeleteRecord(forms.Form):
|
||||||
|
@ -96,4 +109,6 @@ class FormDeleteRecord(forms.Form):
|
||||||
zone_name = forms.CharField(max_length=256)
|
zone_name = forms.CharField(max_length=256)
|
||||||
rr_list = CustomUnicodeListField()
|
rr_list = CustomUnicodeListField()
|
||||||
key_name = forms.ModelChoiceField(queryset=Key.objects.all(),
|
key_name = forms.ModelChoiceField(queryset=Key.objects.all(),
|
||||||
required=False)
|
required=False,
|
||||||
|
widget=forms.RadioSelect,
|
||||||
|
empty_label=None)
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
# Binder Helpers
|
# Binder Helpers
|
||||||
|
|
||||||
# Standard Imports
|
# Standard Imports
|
||||||
|
import logging
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
# 3rd Party
|
# 3rd Party
|
||||||
import dns.query
|
import dns.query
|
||||||
|
import dns.rcode
|
||||||
import dns.reversename
|
import dns.reversename
|
||||||
import dns.tsig
|
import dns.tsig
|
||||||
import dns.tsigkeyring
|
import dns.tsigkeyring
|
||||||
|
@ -13,6 +15,7 @@ import dns.update
|
||||||
|
|
||||||
# App Imports
|
# App Imports
|
||||||
from binder import models
|
from binder import models
|
||||||
|
from binder.exceptions import KeyringException, RecordException
|
||||||
|
|
||||||
|
|
||||||
def add_record(dns_server, zone_name, record_name, record_type, record_data,
|
def add_record(dns_server, zone_name, record_name, record_type, record_data,
|
||||||
|
@ -89,11 +92,13 @@ def delete_record(dns_server, rr_list, key_name):
|
||||||
"""Delete a list of DNS records passed as strings in rr_items."""
|
"""Delete a list of DNS records passed as strings in rr_items."""
|
||||||
server = models.BindServer.objects.get(hostname=dns_server)
|
server = models.BindServer.objects.get(hostname=dns_server)
|
||||||
|
|
||||||
|
logger = logging.getLogger('binder.helpers')
|
||||||
try:
|
try:
|
||||||
transfer_key = models.Key.objects.get(name=key_name)
|
transfer_key = models.Key.objects.get(name=key_name)
|
||||||
except models.Key.DoesNotExist:
|
except models.Key.DoesNotExist as exc:
|
||||||
keyring = None
|
logger.error(exc)
|
||||||
algorithm = None
|
raise KeyringException("The specified TSIG key %s does not exist in "
|
||||||
|
"binders configuration." % key_name)
|
||||||
else:
|
else:
|
||||||
keyring = transfer_key.create_keyring()
|
keyring = transfer_key.create_keyring()
|
||||||
algorithm = transfer_key.algorithm
|
algorithm = transfer_key.algorithm
|
||||||
|
@ -107,13 +112,19 @@ def delete_record(dns_server, rr_list, key_name):
|
||||||
keyring=keyring,
|
keyring=keyring,
|
||||||
keyalgorithm=algorithm)
|
keyalgorithm=algorithm)
|
||||||
dns_update.delete(record)
|
dns_update.delete(record)
|
||||||
|
try:
|
||||||
output = send_dns_update(dns_update,
|
output = send_dns_update(dns_update,
|
||||||
dns_server,
|
dns_server,
|
||||||
server.dns_port,
|
server.dns_port,
|
||||||
key_name)
|
key_name)
|
||||||
|
except (KeyringException, RecordException) as exc:
|
||||||
delete_response.append({"description": "Delete Record: %s" % current_rr,
|
delete_response.append({"description": exc,
|
||||||
"output": output})
|
"record": current_rr,
|
||||||
|
"success": False})
|
||||||
|
else:
|
||||||
|
delete_response.append({"description": output,
|
||||||
|
"record": current_rr,
|
||||||
|
"success": True})
|
||||||
|
|
||||||
return delete_response
|
return delete_response
|
||||||
|
|
||||||
|
@ -123,11 +134,13 @@ def create_update(dns_server, zone_name, record_name, record_type, record_data,
|
||||||
"""Update/Create DNS record of name and type with passed data and ttl."""
|
"""Update/Create DNS record of name and type with passed data and ttl."""
|
||||||
server = models.BindServer.objects.get(hostname=dns_server)
|
server = models.BindServer.objects.get(hostname=dns_server)
|
||||||
|
|
||||||
|
logger = logging.getLogger('binder.helpers')
|
||||||
try:
|
try:
|
||||||
transfer_key = models.Key.objects.get(name=key_name)
|
transfer_key = models.Key.objects.get(name=key_name)
|
||||||
except models.Key.DoesNotExist:
|
except models.Key.DoesNotExist as exc:
|
||||||
keyring = None
|
logger.error(exc)
|
||||||
algorithm = None
|
raise KeyringException("The specified TSIG key %s does not exist in "
|
||||||
|
"binders configuration." % key_name)
|
||||||
else:
|
else:
|
||||||
keyring = transfer_key.create_keyring()
|
keyring = transfer_key.create_keyring()
|
||||||
algorithm = transfer_key.algorithm
|
algorithm = transfer_key.algorithm
|
||||||
|
@ -174,13 +187,21 @@ def send_dns_update(dns_message, dns_server, port, key_name):
|
||||||
Returns:
|
Returns:
|
||||||
String output
|
String output
|
||||||
"""
|
"""
|
||||||
|
logger = logging.getLogger('binder.helpers')
|
||||||
try:
|
try:
|
||||||
output = dns.query.tcp(dns_message, dns_server, port=port)
|
output = dns.query.tcp(dns_message, dns_server, port=port)
|
||||||
except dns.tsig.PeerBadKey:
|
except dns.tsig.PeerBadKey as exc:
|
||||||
output = ("DNS server %s is not configured for TSIG key: %s." %
|
logger.error(exc)
|
||||||
|
raise KeyringException("DNS server %s is not configured for TSIG key: %s." %
|
||||||
(dns_server, key_name))
|
(dns_server, key_name))
|
||||||
except dns.tsig.PeerBadSignature:
|
except dns.tsig.PeerBadSignature as exc:
|
||||||
output = ("DNS server %s did like the TSIG signature we sent. Check "
|
logger.error(exc)
|
||||||
"key %s for correctness." % (dns_server, key_name))
|
raise KeyringException("DNS server %s didn't like the TSIG signature "
|
||||||
|
"we sent. Check key %s for correctness." %
|
||||||
|
(dns_server, key_name))
|
||||||
|
logger.debug(output)
|
||||||
|
return_code = output.rcode()
|
||||||
|
if return_code != dns.rcode.NOERROR:
|
||||||
|
raise RecordException('Error when requesting DNS server %s: %s' %
|
||||||
|
(dns_server, dns.rcode.to_text(return_code)))
|
||||||
return output
|
return output
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# Django settings for binder project.
|
# Django settings for binder project.
|
||||||
import os
|
import os
|
||||||
|
from django.contrib.messages import constants as messages
|
||||||
|
|
||||||
SITE_ROOT = os.path.dirname(os.path.realpath(__file__))
|
SITE_ROOT = os.path.dirname(os.path.realpath(__file__))
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
|
@ -88,6 +89,38 @@ INSTALLED_APPS = (
|
||||||
|
|
||||||
TEST_RUNNER = 'django.test.runner.DiscoverRunner'
|
TEST_RUNNER = 'django.test.runner.DiscoverRunner'
|
||||||
|
|
||||||
|
LOGGING = {
|
||||||
|
'version': 1,
|
||||||
|
'disable_existing_loggers': False,
|
||||||
|
'formatters': {
|
||||||
|
'verbose': {
|
||||||
|
'format' : "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",
|
||||||
|
'datefmt' : "%d/%b/%Y %H:%M:%S"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'handlers': {
|
||||||
|
'console': {
|
||||||
|
'class': 'logging.StreamHandler',
|
||||||
|
'formatter': 'verbose'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'loggers': {
|
||||||
|
'django': {
|
||||||
|
'handlers': ['console'],
|
||||||
|
'propagate': True,
|
||||||
|
'level': 'INFO'
|
||||||
|
},
|
||||||
|
'binder': {
|
||||||
|
'handlers': ['console'],
|
||||||
|
'level': 'DEBUG'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MESSAGE_TAGS = {
|
||||||
|
messages.ERROR: 'danger'
|
||||||
|
}
|
||||||
|
|
||||||
TTL_CHOICES = ((300, "5 minutes"),
|
TTL_CHOICES = ((300, "5 minutes"),
|
||||||
(1800, "30 minutes"),
|
(1800, "30 minutes"),
|
||||||
(3600, "1 hour"),
|
(3600, "1 hour"),
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
<script src="{% static "sorttable.js" %}"></script>
|
<script src="{% static "sorttable.js" %}"></script>
|
||||||
</head>
|
</head>
|
||||||
{% endblock header %}
|
{% endblock header %}
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<script src="{% static "jquery-2.1.3.min.js" %}"></script>
|
<script src="{% static "jquery-2.1.3.min.js" %}"></script>
|
||||||
<script src="{% static "bootstrap/js/bootstrap.min.js" %}"></script>
|
<script src="{% static "bootstrap/js/bootstrap.min.js" %}"></script>
|
||||||
|
@ -46,23 +45,17 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
{% block errors %}
|
{% if messages %}
|
||||||
{% if errors %}
|
<ul id="messages" class="list-unstyled text-center" style="margin-bottom: 2em;">
|
||||||
<div class="alert alert-error">
|
{% for message in messages %}
|
||||||
Errors were encountered:
|
<li role="alert" class="alert alert-{{ message.tags }} alert-dismissible"><button aria-label="Close" data-dismiss="alert" class="close" type="button"><span aria-hidden="true">×</span></button>{{ message.message }}</li>
|
||||||
<br />
|
{% endfor %}
|
||||||
{{ errors }}
|
</ul>
|
||||||
</div>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock errors %}
|
{% block body %}{% endblock body %}
|
||||||
|
|
||||||
{% block body %}
|
|
||||||
{% endblock body %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% block footer %}{% endblock footer %}
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
{% block footer %}
|
|
||||||
{% endblock footer %}
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block pageheader %}Add CNAME record for {{ originating_record }}{% endblock pageheader %}
|
{% block pageheader %}Add CNAME record for {{ form.originating_record.value }}.{{ form.zone_name.value }}{% endblock pageheader %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<form class="form-horizontal" action="{% url "add_cname_result" %}" method="post">{% csrf_token %}
|
<form class="form-horizontal" action="{% url "add_cname" dns_server=dns_server zone_name=form.zone_name.value record_name=originating_record %}" method="post">{% csrf_token %}
|
||||||
<legend>Create CNAME record</legend>
|
<legend>Create CNAME record</legend>
|
||||||
|
|
||||||
<div class="form-group{% if form.dns_server.errors %} has-error{% endif %}">
|
<div class="form-group{% if form.dns_server.errors %} has-error{% endif %}">
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
<div class="form-group{% if form.originating_record.errors %} has-error{% endif %}">
|
<div class="form-group{% if form.originating_record.errors %} has-error{% endif %}">
|
||||||
<label for="originating_record" class="col-sm-3 control-label">Originating Record: </label>
|
<label for="originating_record" class="col-sm-3 control-label">Originating Record: </label>
|
||||||
<div class="col-sm-5 col-md-4">
|
<div class="col-sm-5 col-md-4">
|
||||||
<input type="text" id="originating_record" name="originating_record" class="form-control" value="{{originating_record}}" readonly="readonly"/>
|
<input type="text" id="originating_record" name="originating_record" class="form-control" value="{{ form.originating_record.value }}" readonly="readonly"/>
|
||||||
</div>
|
</div>
|
||||||
{% if form.originating_record.errors %}
|
{% if form.originating_record.errors %}
|
||||||
<div class="col-sm-4 col-md-5">
|
<div class="col-sm-4 col-md-5">
|
||||||
|
@ -41,8 +41,8 @@
|
||||||
<div class="col-sm-5 col-md-4">
|
<div class="col-sm-5 col-md-4">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="cname" name="cname" type="text" class="form-control"{% if form.cname.value %} value="{{ form.cname.value }}"{% endif %}/>
|
<input id="cname" name="cname" type="text" class="form-control"{% if form.cname.value %} value="{{ form.cname.value }}"{% endif %}/>
|
||||||
<span class="input-group-addon">.{{zone_name}}</span>
|
<span class="input-group-addon">.{{ form.zone_name.value }}</span>
|
||||||
<input type="hidden" name="zone_name" value="{{zone_name}}"/>
|
<input type="hidden" name="zone_name" value="{{ form.zone_name.value }}"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if form.cname.errors %}
|
{% if form.cname.errors %}
|
||||||
|
@ -58,10 +58,8 @@
|
||||||
<label for="ttl" class="col-sm-3 control-label">TTL: </label>
|
<label for="ttl" class="col-sm-3 control-label">TTL: </label>
|
||||||
<div class="col-sm-5 col-md-4">
|
<div class="col-sm-5 col-md-4">
|
||||||
<select id="ttl" name="ttl" class="form-control">
|
<select id="ttl" name="ttl" class="form-control">
|
||||||
{% for ttl, description in ttl_choices %}
|
{% for choice in form.ttl %}
|
||||||
<option value="{{ttl}}">
|
<option value="{{ choice.choice_value }}">{{ choice.choice_value }} ({{ choice.choice_label }})</option>
|
||||||
{{ttl}} ({{description}})
|
|
||||||
</option>
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
@ -79,10 +77,10 @@
|
||||||
<label for="key_name" class="col-sm-3 control-label">TSIG Key:</label>
|
<label for="key_name" class="col-sm-3 control-label">TSIG Key:</label>
|
||||||
<div class="col-sm-5 col-md-4">
|
<div class="col-sm-5 col-md-4">
|
||||||
<select id="key_name" name="key_name" class="form-control">
|
<select id="key_name" name="key_name" class="form-control">
|
||||||
{% for key in tsig_keys %}
|
{% for key in form.key_name %}
|
||||||
<option value="{{key.id}}"{% if key == dns_server.default_transfer_key %} selected="selected"{% endif %}>{{key}}</option>
|
<option value="{{ key.choice_value }}"{% if key.choice_value|add:0 == dns_server.default_transfer_key.id %} selected="selected"{% endif %}>{{ key.choice_label }}</option>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<option selected="selected" value=""/>
|
<option selected="selected" value="" />
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
@ -100,7 +98,7 @@
|
||||||
<div class="col-sm-3"></div>
|
<div class="col-sm-3"></div>
|
||||||
<div class="col-sm-5 col-md-4">
|
<div class="col-sm-5 col-md-4">
|
||||||
<button type="submit" class="btn btn-default">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=form.zone_name.value %}" class="btn btn-warning">Cancel</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block pageheader %}Add record in {{ zone_name }}{% endblock pageheader %}
|
{% block pageheader %}Add record in {{ form.zone_name.value }}{% endblock pageheader %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<form class="form-horizontal" action="{% url "add_record_result" %}" method="POST">{% csrf_token %}
|
<form class="form-horizontal" action="{% url "add_record" dns_server=dns_server zone_name=form.zone_name.value %}" method="POST">{% csrf_token %}
|
||||||
<legend>Create Record</legend>
|
<legend>Create Record</legend>
|
||||||
|
|
||||||
<div class="form-group{% if form.dns_server.errors %} has-error{% endif %}">
|
<div class="form-group{% if form.dns_server.errors %} has-error{% endif %}">
|
||||||
|
@ -26,8 +26,8 @@
|
||||||
<div class="col-sm-5 col-md-4">
|
<div class="col-sm-5 col-md-4">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="record_name" name="record_name" type="text" class="form-control"{% if form.record_name.value %} value="{{ form.record_name.value }}"{% endif %} />
|
<input id="record_name" name="record_name" type="text" class="form-control"{% if form.record_name.value %} value="{{ form.record_name.value }}"{% endif %} />
|
||||||
<span class="input-group-addon">.{{zone_name}}</span>
|
<span class="input-group-addon">.{{ form.zone_name.value }}</span>
|
||||||
<input type="hidden" name="zone_name" value="{{zone_name}}" />
|
<input type="hidden" name="zone_name" value="{{ form.zone_name.value }}" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if form.record_name.errors %}
|
{% if form.record_name.errors %}
|
||||||
|
@ -43,9 +43,9 @@
|
||||||
<label for="record_type" class="col-sm-3 control-label">Record Type:</label>
|
<label for="record_type" class="col-sm-3 control-label">Record Type:</label>
|
||||||
<div class="col-sm-5 col-md-4">
|
<div class="col-sm-5 col-md-4">
|
||||||
<select id="record_type" name="record_type" class="form-control">
|
<select id="record_type" name="record_type" class="form-control">
|
||||||
{% if "in-addr.arpa" not in zone_name and "ip6.arpa" not in zone_name %}
|
{% if "in-addr.arpa" not in form.zone_name.value and "ip6.arpa" not in form.zone_name.value %}
|
||||||
{% for type, name in record_type_choices %}
|
{% for choice in form.record_type %}
|
||||||
<option value="{{name}}">{{name}}</option>
|
<option value="{{ choice.choice_value }}">{{ choice.choice_label }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<option value="PTR">PTR</option>
|
<option value="PTR">PTR</option>
|
||||||
|
@ -80,10 +80,8 @@
|
||||||
<label for="ttl" class="col-sm-3 control-label">TTL: </label>
|
<label for="ttl" class="col-sm-3 control-label">TTL: </label>
|
||||||
<div class="col-sm-5 col-md-4">
|
<div class="col-sm-5 col-md-4">
|
||||||
<select id="ttl" name="ttl" class="form-control">
|
<select id="ttl" name="ttl" class="form-control">
|
||||||
{% for ttl, description in ttl_choices %}
|
{% for choice in form.ttl %}
|
||||||
<option value="{{ttl}}">
|
<option value="{{ choice.choice_value }}">{{ choice.choice_value }} ({{ choice.choice_label }})</option>
|
||||||
{{ttl}} ({{description}})
|
|
||||||
</option>
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
@ -97,7 +95,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if "in-addr.arpa" not in zone_name and "ip.arpa" not in zone_name %}
|
{% if "in-addr.arpa" not in form.zone_name.value and "ip.arpa" not in form.zone_name.value %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="create_reverse" class="col-sm-3 control-label checkbox">Create Reverse Record (PTR):</label>
|
<label for="create_reverse" class="col-sm-3 control-label checkbox">Create Reverse Record (PTR):</label>
|
||||||
<div class="col-sm-5 col-md-4">
|
<div class="col-sm-5 col-md-4">
|
||||||
|
@ -110,10 +108,10 @@
|
||||||
<label for="key_name" class="col-sm-3 control-label">TSIG Key:</label>
|
<label for="key_name" class="col-sm-3 control-label">TSIG Key:</label>
|
||||||
<div class="col-sm-5 col-md-4">
|
<div class="col-sm-5 col-md-4">
|
||||||
<select id="key_name" name="key_name" class="form-control">
|
<select id="key_name" name="key_name" class="form-control">
|
||||||
{% for key in tsig_keys %}
|
{% for key in form.key_name %}
|
||||||
<option value="{{key.id}}"{% if key == dns_server.default_transfer_key %} selected="selected"{% endif %}>{{key}}</option>
|
<option value="{{ key.choice_value }}"{% if key.choice_value|add:0 == dns_server.default_transfer_key.id %} selected="selected"{% endif %}>{{ key.choice_label }}</option>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<option selected="selected" value=""/>
|
<option selected="selected" value="" />
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
@ -131,7 +129,7 @@
|
||||||
<div class="col-sm-3"></div>
|
<div class="col-sm-3"></div>
|
||||||
<div class="col-sm-5 col-md-4">
|
<div class="col-sm-5 col-md-4">
|
||||||
<button type="submit" class="btn btn-default">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=form.zone_name.value %}" class="btn btn-warning">Cancel</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
{% block pageheader %}Delete record(s) in {{ zone_name }}{% endblock pageheader %}
|
{% block pageheader %}Delete record(s) in {{ zone_name }}{% endblock pageheader %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<form class="form-horizontal" action="{% url "delete_record_result" %}" method="POST">{% csrf_token %}
|
<form class="form-horizontal" action="{% url "delete_record" dns_server=dns_server zone_name=zone_name %}" method="POST">{% csrf_token %}
|
||||||
<legend>Delete Record</legend>
|
<legend>Delete Record</legend>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@ -39,10 +39,10 @@
|
||||||
<label for="key_name" class="col-sm-3 control-label">TSIG Key:</label>
|
<label for="key_name" class="col-sm-3 control-label">TSIG Key:</label>
|
||||||
<div class="col-sm-5 col-md-4">
|
<div class="col-sm-5 col-md-4">
|
||||||
<select id="key_name" name="key_name" class="form-control">
|
<select id="key_name" name="key_name" class="form-control">
|
||||||
{% for key in tsig_keys %}
|
{% for key in form.key_name %}
|
||||||
<option value="{{key.id}}"{% if key == dns_server.default_transfer_key %} selected="selected"{% endif %}>{{key}}</option>
|
<option value="{{ key.choice_value }}"{% if key.choice_value|add:0 == dns_server.default_transfer_key.id %} selected="selected"{% endif %}>{{ key.choice_label }}</option>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<option selected="selected" value=""/>
|
<option selected="selected" value="" />
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
|
@ -3,13 +3,9 @@
|
||||||
{% block pageheader %}Zone listing for {{ zone_name }} on {{ dns_server.hostname }}{% endblock pageheader %}
|
{% block pageheader %}Zone listing for {{ zone_name }} on {{ dns_server.hostname }}{% endblock pageheader %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
{% if not errors %}
|
<p><a href="{% url "add_record" dns_server=dns_server zone_name=zone_name %}" class="btn btn-default">Add Record</a></p>
|
||||||
<a href="{% url "add_record" dns_server=dns_server zone_name=zone_name %}" class="btn btn-default">Add Record</a>
|
|
||||||
|
|
||||||
<form action="{% url "delete_record" %}" method="post">{% csrf_token %}
|
<form action="{% url "delete_record" dns_server=dns_server zone_name=zone_name %}" 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="sortable table table-condensed table-hover">
|
<table class="sortable table table-condensed table-hover">
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -48,7 +44,6 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<button class="btn btn-danger" type="submit">Delete Selected</button>
|
<p><button class="btn btn-danger" type="submit">Delete Selected</button></p>
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
|
||||||
{% endblock body %}
|
{% endblock body %}
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
{% extends "base.html" %}
|
|
||||||
|
|
||||||
{% block pageheader %}Record Result{% endblock pageheader %}
|
|
||||||
|
|
||||||
{% block body %}
|
|
||||||
<table class="table">
|
|
||||||
{% for current_response in response %}
|
|
||||||
<tr>
|
|
||||||
<th>Record</th>
|
|
||||||
<th>Output</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{ current_response.description }}</td>
|
|
||||||
<td><pre>{{ current_response.output }}</pre></td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</table>
|
|
||||||
{% endblock body %}
|
|
|
@ -27,18 +27,6 @@ class GetTests(TestCase):
|
||||||
response = self.client.get(reverse("server_list"))
|
response = self.client.get(reverse("server_list"))
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
def test_GetResultRedirects(self):
|
|
||||||
"""GETing a /result/ URL should always redirect to /."""
|
|
||||||
response = self.client.get(reverse("add_record_result"), follow=True)
|
|
||||||
self.assertRedirects(response, reverse("index"))
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
response = self.client.get(reverse("delete_record_result"), follow=True)
|
|
||||||
self.assertRedirects(response, reverse("index"))
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
response = self.client.get(reverse("add_cname_result"), follow=True)
|
|
||||||
self.assertRedirects(response, reverse("index"))
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
|
|
||||||
def test_GetInvalidServer(self):
|
def test_GetInvalidServer(self):
|
||||||
"""Get a zone list for a server not in the database."""
|
"""Get a zone list for a server not in the database."""
|
||||||
server_name = "unconfigured.server.net"
|
server_name = "unconfigured.server.net"
|
||||||
|
@ -64,28 +52,31 @@ class PostTests(TestCase):
|
||||||
|
|
||||||
def test_DeleteRecordInitial_Empty(self):
|
def test_DeleteRecordInitial_Empty(self):
|
||||||
"""Ensure the initial deletion form works as expected with no RR list."""
|
"""Ensure the initial deletion form works as expected with no RR list."""
|
||||||
response = self.client.post(reverse("delete_record"),
|
dns_server = "testserver.test.net"
|
||||||
{"dns_server": "testserver.test.net",
|
zone_name = "testzone1.test.net"
|
||||||
"zone_name": "testzone1.test.net",
|
response = self.client.post(reverse("delete_record",
|
||||||
"rr_list": []})
|
kwargs={'dns_server': dns_server,
|
||||||
|
'zone_name': zone_name}),
|
||||||
self.assertContains(response,
|
{"rr_list": []}, follow=True)
|
||||||
'<input type="hidden" id="zone_name" name="zone_name" value="testzone1.test.net" />',
|
self.assertRedirects(response,
|
||||||
html=True)
|
reverse("zone_list",
|
||||||
self.assertContains(response,
|
kwargs={'dns_server': dns_server,
|
||||||
'<input type="hidden" id="rr_list" name="rr_list" value="[]" />',
|
'zone_name': zone_name}))
|
||||||
html=True)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertContains(response,
|
self.assertContains(response, "Select at least one record for deletion.")
|
||||||
'<input type="hidden" id="dns_server" name="dns_server" value="testserver.test.net" />',
|
|
||||||
html=True)
|
|
||||||
|
|
||||||
|
|
||||||
def test_DeleteRecordInitial(self):
|
def test_DeleteRecordInitial(self):
|
||||||
"""Ensure the initial deletion form works as expected with RRs mentioned."""
|
"""Ensure the initial deletion form works as expected with RRs mentioned."""
|
||||||
response = self.client.post(reverse("delete_record"), {"dns_server": "testserver.test.net",
|
dns_server = "testserver.test.net"
|
||||||
"zone_name": "testzone1.test.net",
|
zone_name = "testzone1.test.net"
|
||||||
"rr_list": ["testrecord1.testzone1.test.net",
|
response = self.client.post(reverse("delete_record",
|
||||||
|
kwargs={'dns_server': dns_server,
|
||||||
|
'zone_name': zone_name}),
|
||||||
|
{"rr_list": ["testrecord1.testzone1.test.net",
|
||||||
"testrecord2.testzone1.test.net"]})
|
"testrecord2.testzone1.test.net"]})
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertContains(response,
|
self.assertContains(response,
|
||||||
'<input type="hidden" id="zone_name" name="zone_name" value="testzone1.test.net" />', html=True)
|
'<input type="hidden" id="zone_name" name="zone_name" value="testzone1.test.net" />', html=True)
|
||||||
self.assertContains(response,
|
self.assertContains(response,
|
||||||
|
|
|
@ -15,11 +15,6 @@ urlpatterns = patterns('',
|
||||||
url(r'^info/(?P<dns_server>[a-zA-Z0-9.-]+)/(?P<zone_name>[a-zA-Z0-9.-]+)/$', 'binder.views.view_zone_records', name="zone_list"),
|
url(r'^info/(?P<dns_server>[a-zA-Z0-9.-]+)/(?P<zone_name>[a-zA-Z0-9.-]+)/$', 'binder.views.view_zone_records', name="zone_list"),
|
||||||
|
|
||||||
url(r'^add_record/(?P<dns_server>[a-zA-Z0-9.-]+)/(?P<zone_name>[a-zA-Z0-9.-]+)/$', 'binder.views.view_add_record', name="add_record"),
|
url(r'^add_record/(?P<dns_server>[a-zA-Z0-9.-]+)/(?P<zone_name>[a-zA-Z0-9.-]+)/$', 'binder.views.view_add_record', name="add_record"),
|
||||||
url(r'^add_record/result/$', 'binder.views.view_add_record_result', name="add_record_result"),
|
|
||||||
|
|
||||||
url(r'^delete_record/$', 'binder.views.view_delete_record', name="delete_record"),
|
|
||||||
url(r'^delete_record/result/$', 'binder.views.view_delete_result', name="delete_record_result"),
|
|
||||||
|
|
||||||
url(r'^add_cname/(?P<dns_server>[a-zA-Z0-9.-]+)/(?P<zone_name>[a-zA-Z0-9.-]+)/(?P<record_name>.*?)/$', 'binder.views.view_add_cname_record', name="add_cname"),
|
url(r'^add_cname/(?P<dns_server>[a-zA-Z0-9.-]+)/(?P<zone_name>[a-zA-Z0-9.-]+)/(?P<record_name>.*?)/$', 'binder.views.view_add_cname_record', name="add_cname"),
|
||||||
url(r'^add_cname_record/result/$', 'binder.views.view_add_cname_result', name="add_cname_result"),
|
url(r'^delete_record/(?P<dns_server>[a-zA-Z0-9.-]+)/(?P<zone_name>[a-zA-Z0-9.-]+)/$', 'binder.views.view_delete_record', name="delete_record"),
|
||||||
)
|
)
|
||||||
|
|
201
binder/views.py
201
binder/views.py
|
@ -1,12 +1,12 @@
|
||||||
# Binder VIews
|
# Binder VIews
|
||||||
|
|
||||||
# 3rd Party
|
# 3rd Party
|
||||||
from django.conf import settings
|
from django.contrib import messages
|
||||||
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 forms, helpers, models
|
||||||
|
from binder.exceptions import KeyringException, RecordException, TransferException, ZoneException
|
||||||
|
|
||||||
def home_index(request):
|
def home_index(request):
|
||||||
"""List the main index page for Binder."""
|
"""List the main index page for Binder."""
|
||||||
|
@ -27,75 +27,49 @@ def view_server_list(request):
|
||||||
|
|
||||||
def view_server_zones(request, dns_server):
|
def view_server_zones(request, dns_server):
|
||||||
"""Display the list of DNS zones a particular DNS host provides."""
|
"""Display the list of DNS zones a particular DNS host provides."""
|
||||||
errors = ""
|
|
||||||
zone_array = {}
|
zone_array = {}
|
||||||
|
|
||||||
this_server = get_object_or_404(models.BindServer, hostname=dns_server)
|
this_server = get_object_or_404(models.BindServer, hostname=dns_server)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
zone_array = this_server.list_zones()
|
zone_array = this_server.list_zones()
|
||||||
except exceptions.ZoneException, err:
|
except ZoneException as exc:
|
||||||
errors = "Unable to list server zones. Error: %s" % err
|
messages.error(request, "Unable to list server zones. Error: %s" % exc)
|
||||||
|
|
||||||
return render(request, "bcommon/list_server_zones.html",
|
return render(request, "bcommon/list_server_zones.html",
|
||||||
{"errors": errors,
|
{"dns_server": this_server,
|
||||||
"dns_server": this_server,
|
|
||||||
"zone_array": zone_array})
|
"zone_array": zone_array})
|
||||||
|
|
||||||
|
|
||||||
def view_zone_records(request, dns_server, zone_name):
|
def view_zone_records(request, dns_server, zone_name):
|
||||||
"""Display the list of records for a particular zone."""
|
"""Display the list of records for a particular zone."""
|
||||||
errors = ""
|
|
||||||
zone_array = {}
|
zone_array = {}
|
||||||
|
|
||||||
this_server = get_object_or_404(models.BindServer, hostname=dns_server)
|
this_server = get_object_or_404(models.BindServer, hostname=dns_server)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
zone_array = this_server.list_zone_records(zone_name)
|
zone_array = this_server.list_zone_records(zone_name)
|
||||||
except exceptions.TransferException, err:
|
except TransferException as exc:
|
||||||
return render(request, "bcommon/list_zone.html",
|
return render(request, "bcommon/list_zone.html",
|
||||||
{"errors": err,
|
{"zone_name": zone_name,
|
||||||
"zone_name": zone_name,
|
|
||||||
"dns_server": this_server})
|
"dns_server": this_server})
|
||||||
|
|
||||||
return render(request, "bcommon/list_zone.html",
|
return render(request, "bcommon/list_zone.html",
|
||||||
{"zone_array": zone_array,
|
{"zone_array": zone_array,
|
||||||
"dns_server": this_server,
|
"dns_server": this_server,
|
||||||
"zone_name": zone_name,
|
"zone_name": zone_name})
|
||||||
"errors": errors})
|
|
||||||
|
|
||||||
|
|
||||||
def view_add_record(request, dns_server, zone_name):
|
def view_add_record(request, dns_server, zone_name):
|
||||||
"""View to provide form to add a DNS record."""
|
"""View to allow to add A records."""
|
||||||
this_server = get_object_or_404(models.BindServer, hostname=dns_server)
|
this_server = get_object_or_404(models.BindServer, hostname=dns_server)
|
||||||
|
|
||||||
return render(request, "bcommon/add_record_form.html",
|
if request.method == 'POST':
|
||||||
{"dns_server": this_server,
|
|
||||||
"zone_name": zone_name,
|
|
||||||
"tsig_keys": models.Key.objects.all(),
|
|
||||||
"ttl_choices": settings.TTL_CHOICES,
|
|
||||||
"record_type_choices": settings.RECORD_TYPE_CHOICES})
|
|
||||||
|
|
||||||
|
|
||||||
def view_add_record_result(request):
|
|
||||||
"""Process the input given to add a DNS record."""
|
|
||||||
errors = ""
|
|
||||||
if request.method == "GET":
|
|
||||||
return redirect("/")
|
|
||||||
|
|
||||||
if "HTTP_REFERER" in request.META:
|
|
||||||
incoming_zone = request.META["HTTP_REFERER"].split("/")[-2]
|
|
||||||
if ("in-addr.arpa" in incoming_zone) or ("ip6.arpa" in incoming_zone):
|
|
||||||
form = forms.FormAddReverseRecord(request.POST)
|
|
||||||
else:
|
|
||||||
form = forms.FormAddForwardRecord(request.POST)
|
form = forms.FormAddForwardRecord(request.POST)
|
||||||
else:
|
|
||||||
form = forms.FormAddForwardRecord(request.POST)
|
|
||||||
|
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form_cleaned = form.cleaned_data
|
form_cleaned = form.cleaned_data
|
||||||
try:
|
try:
|
||||||
response = helpers.add_record(form_cleaned["dns_server"],
|
helpers.add_record(form_cleaned["dns_server"],
|
||||||
str(form_cleaned["zone_name"]),
|
str(form_cleaned["zone_name"]),
|
||||||
str(form_cleaned["record_name"]),
|
str(form_cleaned["record_name"]),
|
||||||
str(form_cleaned["record_type"]),
|
str(form_cleaned["record_type"]),
|
||||||
|
@ -103,108 +77,97 @@ def view_add_record_result(request):
|
||||||
form_cleaned["ttl"],
|
form_cleaned["ttl"],
|
||||||
form_cleaned["key_name"],
|
form_cleaned["key_name"],
|
||||||
form_cleaned["create_reverse"])
|
form_cleaned["create_reverse"])
|
||||||
except exceptions.RecordException, err:
|
except (KeyringException, RecordException) as exc:
|
||||||
# TODO: Start using this exception.
|
messages.error(request, "Adding %s.%s failed: %s" %
|
||||||
# What would cause this?
|
(form_cleaned["record_name"], zone_name, exc))
|
||||||
errors = err
|
else:
|
||||||
|
messages.success(request, "%s.%s was added successfully." %
|
||||||
return render(request, "bcommon/response_result.html",
|
(form_cleaned["record_name"], zone_name))
|
||||||
{"errors": errors,
|
return redirect('zone_list',
|
||||||
"response": response})
|
dns_server=dns_server,
|
||||||
|
zone_name=zone_name)
|
||||||
dns_server = models.BindServer.objects.get(hostname=request.POST["dns_server"])
|
else:
|
||||||
|
form = forms.FormAddForwardRecord(initial={'zone_name': zone_name})
|
||||||
|
|
||||||
return render(request, "bcommon/add_record_form.html",
|
return render(request, "bcommon/add_record_form.html",
|
||||||
{"dns_server": dns_server,
|
{"dns_server": this_server,
|
||||||
"zone_name": request.POST["zone_name"],
|
|
||||||
"tsig_keys": models.Key.objects.all(),
|
|
||||||
"ttl_choices": settings.TTL_CHOICES,
|
|
||||||
"record_type_choices": settings.RECORD_TYPE_CHOICES,
|
|
||||||
"form": form})
|
"form": form})
|
||||||
|
|
||||||
|
|
||||||
def view_add_cname_record(request, dns_server, zone_name, record_name):
|
def view_add_cname_record(request, dns_server, zone_name, record_name):
|
||||||
"""Process given input to add a CNAME pointer."""
|
"""View to allow to add CNAME records."""
|
||||||
this_server = get_object_or_404(models.BindServer, hostname=dns_server)
|
this_server = get_object_or_404(models.BindServer, hostname=dns_server)
|
||||||
|
|
||||||
return render(request, "bcommon/add_cname_record_form.html",
|
if request.method == 'POST':
|
||||||
{"dns_server": this_server,
|
|
||||||
"originating_record": "%s.%s" % (record_name, zone_name),
|
|
||||||
"zone_name": zone_name,
|
|
||||||
"ttl_choices": settings.TTL_CHOICES,
|
|
||||||
"tsig_keys": models.Key.objects.all()})
|
|
||||||
|
|
||||||
|
|
||||||
def view_add_cname_result(request):
|
|
||||||
"""Process input on the CNAME form and provide a response."""
|
|
||||||
if request.method == "GET":
|
|
||||||
return redirect("/")
|
|
||||||
|
|
||||||
errors = ""
|
|
||||||
add_cname_response = ""
|
|
||||||
form = forms.FormAddCnameRecord(request.POST)
|
form = forms.FormAddCnameRecord(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form_cleaned = form.cleaned_data
|
form_cleaned = form.cleaned_data
|
||||||
try:
|
try:
|
||||||
add_cname_response = helpers.add_cname_record(
|
helpers.add_cname_record(form_cleaned["dns_server"],
|
||||||
form_cleaned["dns_server"],
|
str(form_cleaned["zone_name"]),
|
||||||
form_cleaned["zone_name"],
|
str(form_cleaned["cname"]),
|
||||||
form_cleaned["cname"],
|
'%s.%s' % (str(form_cleaned["originating_record"]),
|
||||||
str(form_cleaned["originating_record"]),
|
str(form_cleaned["zone_name"])),
|
||||||
form_cleaned["ttl"],
|
form_cleaned["ttl"],
|
||||||
form_cleaned["key_name"])
|
form_cleaned["key_name"])
|
||||||
except exceptions.RecordException, err:
|
except (KeyringException, RecordException) as exc:
|
||||||
errors = err
|
messages.error(request, "Adding %s.%s failed: %s" %
|
||||||
|
(form_cleaned["record_name"], zone_name, exc))
|
||||||
return render(request, "bcommon/response_result.html",
|
else:
|
||||||
{"response": add_cname_response,
|
messages.success(request, "%s.%s was added successfully." %
|
||||||
"errors": errors})
|
(form_cleaned["record_name"], zone_name))
|
||||||
|
return redirect('zone_list',
|
||||||
dns_server = models.BindServer.objects.get(hostname=request.POST["dns_server"])
|
dns_server=dns_server,
|
||||||
|
zone_name=zone_name)
|
||||||
|
else:
|
||||||
|
form = forms.FormAddCnameRecord(initial={'originating_record': record_name,
|
||||||
|
'zone_name': zone_name})
|
||||||
|
|
||||||
return render(request, "bcommon/add_cname_record_form.html",
|
return render(request, "bcommon/add_cname_record_form.html",
|
||||||
{"dns_server": dns_server,
|
{"dns_server": this_server,
|
||||||
"zone_name": request.POST["zone_name"],
|
|
||||||
"record_name": request.POST["cname"],
|
|
||||||
"originating_record": request.POST["originating_record"],
|
|
||||||
"ttl_choices": settings.TTL_CHOICES,
|
|
||||||
"tsig_keys": models.Key.objects.all(),
|
|
||||||
"form": form})
|
"form": form})
|
||||||
|
|
||||||
|
|
||||||
def view_delete_record(request):
|
def view_delete_record(request, dns_server, zone_name):
|
||||||
"""Provide the initial form for deleting records."""
|
"""View to handle the deletion of records."""
|
||||||
if request.method == "GET":
|
dns_server = models.BindServer.objects.get(hostname=dns_server)
|
||||||
return redirect("/")
|
|
||||||
|
|
||||||
dns_server = models.BindServer.objects.get(hostname=request.POST["dns_server"])
|
|
||||||
zone_name = request.POST["zone_name"]
|
|
||||||
rr_list = request.POST.getlist("rr_list")
|
rr_list = request.POST.getlist("rr_list")
|
||||||
|
|
||||||
return render(request, "bcommon/delete_record_initial.html",
|
if len(rr_list) == 0:
|
||||||
|
messages.error(request, "Select at least one record for deletion.")
|
||||||
|
return redirect('zone_list',
|
||||||
|
dns_server=dns_server,
|
||||||
|
zone_name=zone_name)
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
form = forms.FormDeleteRecord(request.POST)
|
||||||
|
if form.is_valid():
|
||||||
|
form_cleaned = form.cleaned_data
|
||||||
|
rr_list = form_cleaned["rr_list"]
|
||||||
|
try:
|
||||||
|
response = helpers.delete_record(form_cleaned["dns_server"],
|
||||||
|
rr_list,
|
||||||
|
form_cleaned["key_name"])
|
||||||
|
except KeyringException as exc:
|
||||||
|
for record in rr_list:
|
||||||
|
messages.error(request, "Deleting %s.%s failed: %s" %
|
||||||
|
(record, zone_name, exc))
|
||||||
|
else:
|
||||||
|
for record in response:
|
||||||
|
if record['success'] == True:
|
||||||
|
messages.success(request, "%s.%s was removed successfully." %
|
||||||
|
(record['record'], zone_name))
|
||||||
|
else:
|
||||||
|
messages.error(request, "Deleting %s.%s failed: %s" %
|
||||||
|
(record['record'], zone_name, record['description']))
|
||||||
|
return redirect('zone_list',
|
||||||
|
dns_server=dns_server,
|
||||||
|
zone_name=zone_name)
|
||||||
|
else:
|
||||||
|
form = forms.FormDeleteRecord(initial={'zone_name': zone_name})
|
||||||
|
|
||||||
|
return render(request, "bcommon/delete_record.html",
|
||||||
{"dns_server": dns_server,
|
{"dns_server": dns_server,
|
||||||
"zone_name": zone_name,
|
"zone_name": zone_name,
|
||||||
"rr_list": rr_list,
|
"rr_list": rr_list,
|
||||||
"tsig_keys": models.Key.objects.all()})
|
"form": form})
|
||||||
|
|
||||||
|
|
||||||
def view_delete_result(request):
|
|
||||||
"""View that deletes records and returns the response."""
|
|
||||||
if request.method == "GET":
|
|
||||||
return redirect("/")
|
|
||||||
|
|
||||||
form = forms.FormDeleteRecord(request.POST)
|
|
||||||
|
|
||||||
if form.is_valid():
|
|
||||||
clean_form = form.cleaned_data
|
|
||||||
else:
|
|
||||||
# TODO: What situations would cause this form
|
|
||||||
# not to validate?
|
|
||||||
print "in view_delete_result, form errors: %r" % form.errors
|
|
||||||
|
|
||||||
delete_result = helpers.delete_record(clean_form["dns_server"],
|
|
||||||
clean_form["rr_list"],
|
|
||||||
clean_form["key_name"])
|
|
||||||
|
|
||||||
return render(request, "bcommon/response_result.html",
|
|
||||||
{"response": delete_result})
|
|
||||||
|
|
Loading…
Reference in New Issue