diff --git a/binder/forms.py b/binder/forms.py index 5640ad7..468f950 100644 --- a/binder/forms.py +++ b/binder/forms.py @@ -1,4 +1,9 @@ +### Binder Forms + +# 3rd Party from django import forms + +# App Imports from models import Key TTL_CHOICES = ((300, "5 minutes"), diff --git a/binder/helpers.py b/binder/helpers.py index fc6ffeb..83934d2 100644 --- a/binder/helpers.py +++ b/binder/helpers.py @@ -1,11 +1,17 @@ -from binder import exceptions, keyutils, models +### Binder Helpers +# Standard Imports +from collections import OrderedDict +import re +import socket + +# 3rd Party import dns.query import dns.reversename import dns.update -import dns.tsig -import socket -import re + +# App Imports +from binder import exceptions, keyutils, models def add_record(dns_server, zone_name, record_name, record_type, record_data, ttl, key_name, create_reverse=False): """ Parse passed elements and determine which records to create. @@ -108,19 +114,22 @@ def update_record(dns_server, zone_name, record_name, record_type, record_data, return output -def ip_info(host_name): # , family_dict, socket_dict): +def ip_info(host_name): """Create a dictionary mapping address types to their IP's. If an error is encountered, key to error is "Error". """ - info = {} - + info = [] + ipv4_count = 0 + ipv6_count = 0 try: - for s_family, s_type, s_proto, s_cannoname, s_sockaddr in socket.getaddrinfo(host_name.hostname, None): + for s_family, s_type, s_proto, s_cannoname, s_sockaddr in socket.getaddrinfo(host_name, None): if s_family == 2 and s_type == 1: - info["IPv4"] = s_sockaddr[0] + ipv4_count += 1 + info.append(["IPv4 (%d)" % ipv4_count, s_sockaddr[0]]) if s_family == 10 and s_type == 1: - info["IPv6"] = s_sockaddr[0] + ipv6_count += 1 + info.append(["IPv6 (%d)" % ipv6_count, s_sockaddr[0]]) except socket.gaierror, err: - info["Error"] = "Unable to resolve %s: %s" % (host_name, err) + info.append(["Error", "Unable to resolve %s: %s" % (host_name, err)]) return info diff --git a/binder/models.py b/binder/models.py index 6c3de6b..f492468 100644 --- a/binder/models.py +++ b/binder/models.py @@ -1,14 +1,20 @@ -from django.db import models +### Binder Models +# Standard Imports +import socket +import urllib2 + +# 3rd Party from BeautifulSoup import BeautifulStoneSoup as BS -from binder import exceptions - +import dns.exception import dns.query import dns.tsig import dns.zone + +# App Imports +from binder import exceptions +from django.db import models import keyutils -import socket -import urllib2 TSIG_ALGORITHMS = (('hmac-md5', 'MD5'), ('hmac-sha1', 'SHA1'), @@ -95,15 +101,16 @@ class BindServer(models.Model): try: zone = dns.zone.from_xfr(dns.query.xfr(self.hostname, zone_name, keyring=keyring)) - except dns.exception.FormError, err: - # TODO: What throws this? - raise exceptions.TransferException("There was an error attempting to list zone records.") except dns.tsig.PeerBadKey: # The incorrect TSIG key was selected for transfers. raise exceptions.TransferException("Unable to list zone records because of a TSIG key mismatch.") except socket.error, err: # Thrown when the DNS server does not respond for a zone transfer (XFR). raise exceptions.TransferException("DNS server did not respond for transfer. Reason: %s" % err) + # except exception.FormError, err: + # # TODO: What throws this? + # raise exceptions.TransferException("There was an error attempting to list zone records.") + names = zone.nodes.keys() names.sort() diff --git a/binder/templates/bcommon/list_servers.htm b/binder/templates/bcommon/list_servers.htm index fcf9cca..366b98b 100644 --- a/binder/templates/bcommon/list_servers.htm +++ b/binder/templates/bcommon/list_servers.htm @@ -14,8 +14,8 @@ Server List {% for current_server in server_info %} {{ current_server.host_name }} - {% for key, value in current_server.ip_address.items %} - {{key}}: {{value}}
+ {% for type, data in current_server.ip_address %} + {{type}}: {{data}}
{% endfor %} diff --git a/binder/tests.py b/binder/tests.py index 804b2d0..48619f8 100644 --- a/binder/tests.py +++ b/binder/tests.py @@ -1,7 +1,9 @@ from django.test import TestCase from django.test.client import Client -from binder import models +from binder import models, helpers +from collections import OrderedDict + class GetTests(TestCase): """ Unit Tests that exercise HTTP GET. """ @@ -87,3 +89,16 @@ class PostTests(TestCase): '', html=True) + +class HelperTests(TestCase): + def test_ipinfo_ResolutionFail(self): + response = helpers.ip_info("foobar.doesnotexist.local") + self.assertEqual([['Error', u'Unable to resolve foobar.doesnotexist.local: [Errno -2] Name or service not known']], + response) + # The following is currently the first globally unique IPv4 and IPv6 address I could find + # that did not change based upon your geography. + # http://test-ipv6.com/ + response = helpers.ip_info("ds.test-ipv6.com") + self.assertEqual([['IPv4 (1)', u'216.218.228.114'], ['IPv6 (1)', u'2001:470:1:18::2']], + response) + diff --git a/binder/views.py b/binder/views.py index da20c28..67df271 100644 --- a/binder/views.py +++ b/binder/views.py @@ -1,9 +1,11 @@ +### Binder VIews + +# 3rd Party from django.shortcuts import redirect, render +# App Imports from binder import exceptions, forms, helpers, models -# Views - def home_index(request): """ List the main index page for Binder. """ return render(request, "index.htm") @@ -13,7 +15,7 @@ def view_server_list(request): server_list = models.BindServer.objects.all().order_by("hostname") server_info = [] for current in server_list: - server_info.append({"host_name" : current, "ip_address" : helpers.ip_info(current)}) + server_info.append({"host_name" : current, "ip_address" : helpers.ip_info(current.hostname)}) return render(request, "bcommon/list_servers.htm", { "server_info" : server_info})