Add ability to directly create reverse PTR records. Not the best, but it works.

This commit is contained in:
Jeffrey Forman 2012-12-25 19:57:00 -05:00
parent b803923331
commit 9e95181936
6 changed files with 56 additions and 15 deletions

View File

@ -21,22 +21,45 @@ class CustomUnicodeListField(forms.CharField):
return string_list return string_list
class CustomStringPeriodSuffix(forms.CharField):
""" Convert unicode to string and make sure period is last character. """
### This seems very unclean. Need a better to way to complete the fqdn
### depending on if it ends in a period.
### TODO(jforman): Add Regex check in here for valid rr data
### http://www.zytrax.com/books/dns/apa/names.html
def clean(self, value):
try:
new_string = str(value)
if new_string[-1] != ".":
new_string += "."
except:
raise ValidationError("Unable to stick a period on the end of your input: %r" % value)
return new_string
### Form Models ### Form Models
class FormAddRecord(forms.Form): class FormAddForwardRecord(forms.Form):
""" Form used to add a DNS record. """ Form used to add a Forward DNS record. """
TODO: Right now this form only supports forward zone creation.
It wont accept values if you try to manually add a PTR.
"""
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=local_settings.RECORD_TYPE_CHOICES)
zone_name = forms.CharField(max_length=100) zone_name = forms.CharField(max_length=100)
record_data = forms.GenericIPAddressField() # TODO: Change to this a non-empty valid-data regex field. record_data = forms.GenericIPAddressField()
ttl = forms.ChoiceField(choices=local_settings.TTL_CHOICES) ttl = forms.ChoiceField(choices=local_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)
class FormAddReverseRecord(forms.Form):
""" Form used to add a Reverse (PTR) DNS record. """
dns_server = forms.CharField(max_length=100)
record_name = forms.IntegerField(min_value=0, max_value=255)
record_type = forms.RegexField(regex=r"^PTR$",error_messages={"invalid" : "The only valid choice here is PTR."})
zone_name = forms.CharField(max_length=100)
record_data = CustomStringPeriodSuffix(required=True)
ttl = forms.ChoiceField(choices=local_settings.TTL_CHOICES)
key_name = forms.ModelChoiceField(queryset=Key.objects.all(), required=False)
create_reverse = forms.BooleanField(required=False)
class FormAddCnameRecord(forms.Form): class FormAddCnameRecord(forms.Form):
""" Form used to add a CNAME record. """ """ Form used to add a CNAME record. """
dns_server = forms.CharField(max_length=100) dns_server = forms.CharField(max_length=100)

View File

@ -36,7 +36,7 @@ Add record in {{ zone_name }}
<label class="control-label">Record Type: </label> <label class="control-label">Record Type: </label>
<div class="controls"> <div class="controls">
<select name="record_type"> <select name="record_type">
{% if "in-addr.arpa" not in zone_name and "ip.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 %}
<option value="{{name}}">{{name}}</option> <option value="{{name}}">{{name}}</option>
{% endfor %} {% endfor %}

View File

@ -34,7 +34,7 @@ Zone listing for {{ zone_name }} on {{ dns_server }}
<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 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</a></li> <li><a href="#">Edit Record (Coming Soon)</a></li>
{% if current_record.rr_type == "A" %} {% if current_record.rr_type == "A" %}
<li><a href="{% url add_cname dns_server=dns_server zone_name=zone_name record_name=current_record.rr_name %}">Add CNAME Pointer</a></li> <li><a href="{% url add_cname dns_server=dns_server zone_name=zone_name record_name=current_record.rr_name %}">Add CNAME Pointer</a></li>
{% endif %} {% endif %}

View File

@ -6,6 +6,4 @@ Home
{% block body %} {% block body %}
TODO(jforman): Build some sort of dashboard here
{% endblock body %} {% endblock body %}

View File

@ -14,7 +14,7 @@ class Form_Tests(TestCase):
"key_name": None, "key_name": None,
"create_reverse" : False} "create_reverse" : False}
testform_1 = forms.FormAddRecord(form_data) testform_1 = forms.FormAddForwardRecord(form_data)
self.assertTrue(testform_1.is_valid()) self.assertTrue(testform_1.is_valid())
form_data = {"dns_server":"server1", form_data = {"dns_server":"server1",
@ -26,9 +26,21 @@ class Form_Tests(TestCase):
"key_name":None, "key_name":None,
"create_reverse":True} "create_reverse":True}
testform_2 = forms.FormAddRecord(form_data) testform_2 = forms.FormAddForwardRecord(form_data)
self.assertTrue(testform_2.is_valid()) self.assertTrue(testform_2.is_valid())
form_data = { "dns_server" : "server1",
"record_name" : 41,
"record_type" : "PTR",
"zone_name" : "1.254.10.in-addr.arpa",
"record_data" : "reverse41.domain1.local",
"ttl" : 3600,
"key_name" : None }
reverseform_1 = forms.FormAddReverseRecord(form_data)
reverseform_1.is_valid()
self.assertTrue(reverseform_1.is_valid())
def test_MissingData_FormAddRecord(self): def test_MissingData_FormAddRecord(self):
""" Submit FormAddRecord with missing record_data.""" """ Submit FormAddRecord with missing record_data."""
@ -42,7 +54,7 @@ class Form_Tests(TestCase):
"create_reverse":True} "create_reverse":True}
expected_form_errors = {"record_data": [u"This field is required."]} expected_form_errors = {"record_data": [u"This field is required."]}
testform = forms.FormAddRecord(form_data) testform = forms.FormAddForwardRecord(form_data)
testform.is_valid() testform.is_valid()
self.assertFalse(testform.is_valid()) self.assertFalse(testform.is_valid())
self.assertEquals(expected_form_errors, testform.errors) self.assertEquals(expected_form_errors, testform.errors)
@ -62,7 +74,7 @@ class Form_Tests(TestCase):
"record_name": [u"Enter a valid value."], "record_name": [u"Enter a valid value."],
"record_type": [u"Select a valid choice. 123 is not one of the available choices."], "record_type": [u"Select a valid choice. 123 is not one of the available choices."],
"ttl": [u'Select a valid choice. A is not one of the available choices.']} "ttl": [u'Select a valid choice. A is not one of the available choices.']}
testform_2 = forms.FormAddRecord(form_data) testform_2 = forms.FormAddForwardRecord(form_data)
testform_2.is_valid() testform_2.is_valid()
self.assertFalse(testform_2.is_valid()) self.assertFalse(testform_2.is_valid())
self.assertEquals(expected_form_errors, testform_2.errors) self.assertEquals(expected_form_errors, testform_2.errors)

View File

@ -75,7 +75,15 @@ def view_add_record_result(request):
if request.method == "GET": if request.method == "GET":
return redirect("/") return redirect("/")
form = forms.FormAddRecord(request.POST) 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)
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: