2011-11-24 16:57:13 +00:00
|
|
|
from bcommon.keyutils import create_keyring
|
2011-04-23 15:19:01 +00:00
|
|
|
|
2011-11-24 16:57:13 +00:00
|
|
|
import re
|
2011-04-25 00:52:56 +00:00
|
|
|
import dns.query
|
2011-11-24 16:57:13 +00:00
|
|
|
import dns.reversename
|
|
|
|
import dns.update
|
2011-04-25 00:52:56 +00:00
|
|
|
|
2011-11-25 12:58:43 +00:00
|
|
|
re_IPADDRESS = re.compile(r"\d+.\d+.\d+.\d+")
|
|
|
|
|
2011-11-26 18:03:00 +00:00
|
|
|
def list_zone_records(dns_server, zone_name):
|
2011-11-24 16:57:13 +00:00
|
|
|
"""Take a DNS server and a zone name,
|
|
|
|
and return an array of its records."""
|
2011-04-25 00:52:56 +00:00
|
|
|
# Need to move most of this logic into a helper method.
|
|
|
|
try:
|
2011-11-26 18:03:00 +00:00
|
|
|
zone = dns.zone.from_xfr(dns.query.xfr(dns_server, zone_name))
|
2011-04-25 00:52:56 +00:00
|
|
|
except dns.exception.FormError:
|
|
|
|
# There was an error querying the server for the specific zone.
|
|
|
|
# Example: a zone that does not exist on the server.
|
2011-11-26 18:03:00 +00:00
|
|
|
return { 'errors' : 'Encountered a FormError when querying %s on %s' % (zone_name, dns_server) }
|
2011-11-25 22:43:26 +00:00
|
|
|
except socket.gaierror, err:
|
2011-04-25 00:52:56 +00:00
|
|
|
# TODO: Need to better handle errors here.
|
2011-11-26 18:03:00 +00:00
|
|
|
return { 'errors' : "Problems querying DNS server %s: %s" % (dns_server, err) }
|
2011-04-25 00:52:56 +00:00
|
|
|
|
|
|
|
names = zone.nodes.keys()
|
2011-11-25 22:43:26 +00:00
|
|
|
names.sort()
|
2011-04-25 00:52:56 +00:00
|
|
|
record_array = []
|
|
|
|
for current_name in names:
|
|
|
|
current_record = zone[current_name].to_text(current_name)
|
|
|
|
for split_record in current_record.split("\n"): # Split the records on the newline
|
|
|
|
record_array.append({'rr_name' : split_record.split(" ")[0],
|
|
|
|
'rr_ttl' : split_record.split(" ")[1],
|
|
|
|
'rr_class' : split_record.split(" ")[2],
|
|
|
|
'rr_type' : split_record.split(" ")[3],
|
|
|
|
'rr_data' : split_record.split(" ")[4]})
|
|
|
|
return record_array
|
|
|
|
|
2011-11-24 16:57:13 +00:00
|
|
|
def add_forward_record(form_data, zone_keyring):
|
|
|
|
"""Take in data from FormAddRecord and a keyring object,
|
|
|
|
return a response from the DNS server about adding the record."""
|
|
|
|
|
|
|
|
re_form_data = re.search(r"(\w+).(.*)", form_data["name"])
|
|
|
|
hostname = re_form_data.group(1)
|
|
|
|
domain = re_form_data.group(2)
|
|
|
|
|
|
|
|
dns_update = dns.update.Update(domain, keyring = zone_keyring)
|
2012-01-29 15:47:13 +00:00
|
|
|
if str(form_data["record_type"]) == "CNAME":
|
|
|
|
data_suffix = "."
|
|
|
|
else:
|
|
|
|
data_suffix = ""
|
|
|
|
|
|
|
|
dns_update.replace(hostname, int(form_data["ttl"]), str(form_data["record_type"]), str(form_data["data"]) + data_suffix)
|
2011-11-24 16:57:13 +00:00
|
|
|
|
2011-04-25 01:10:25 +00:00
|
|
|
try:
|
2011-11-24 16:57:13 +00:00
|
|
|
response = dns.query.tcp(dns_update, form_data["dns_server"])
|
|
|
|
except dns.tsig.BadPeerKey:
|
2011-11-25 22:43:26 +00:00
|
|
|
raise Exception("There was a problem adding your forward record due to a TSIG key issue.")
|
2011-11-24 16:57:13 +00:00
|
|
|
|
|
|
|
return response
|
|
|
|
|
|
|
|
def add_reverse_record(form_data, zone_keyring):
|
2012-10-23 00:39:07 +00:00
|
|
|
""" Given a FormAddRecord dict and zone_keyring,
|
|
|
|
add/update a reverse PTR record."""
|
2011-11-24 16:57:13 +00:00
|
|
|
reverse_ip_fqdn = str(dns.reversename.from_address(form_data["data"]))
|
|
|
|
reverse_ip = re.search(r"([0-9]+).(.*).$", reverse_ip_fqdn).group(1)
|
|
|
|
reverse_domain = re.search(r"([0-9]+).(.*).$", reverse_ip_fqdn).group(2)
|
|
|
|
|
|
|
|
dns_update = dns.update.Update(reverse_domain, keyring = zone_keyring)
|
|
|
|
dns_update.replace(reverse_ip, int(form_data["ttl"]), "PTR", str(form_data["name"]) + ".")
|
2011-11-25 12:58:43 +00:00
|
|
|
output = dns.query.tcp(dns_update, form_data["dns_server"])
|
2011-11-24 16:57:13 +00:00
|
|
|
|
2011-11-25 12:58:43 +00:00
|
|
|
return output
|
2011-11-24 16:57:13 +00:00
|
|
|
|
2011-11-25 12:58:43 +00:00
|
|
|
def add_record(form_data):
|
2012-10-23 00:39:07 +00:00
|
|
|
"""Add a DNS record with data from a FormAddRecord dict.
|
2011-11-24 16:57:13 +00:00
|
|
|
If a reverse PTR record is requested, this will be added too."""
|
|
|
|
|
2012-10-13 21:00:22 +00:00
|
|
|
if form_data["key_name"]:
|
2011-11-25 22:43:26 +00:00
|
|
|
keyring = create_keyring(form_data["key_name"])
|
2012-10-13 21:00:22 +00:00
|
|
|
else:
|
|
|
|
keyring = None
|
2011-11-25 22:43:26 +00:00
|
|
|
|
2011-11-24 16:57:13 +00:00
|
|
|
response = {}
|
|
|
|
forward_response = add_forward_record(form_data, keyring)
|
|
|
|
response["forward_response"] = forward_response
|
|
|
|
|
|
|
|
if form_data["create_reverse"]:
|
|
|
|
reverse_response = add_reverse_record(form_data, keyring)
|
|
|
|
response["reverse_response"] = reverse_response
|
2011-04-25 01:10:25 +00:00
|
|
|
|
2011-11-24 16:57:13 +00:00
|
|
|
return response
|
2011-11-25 12:58:43 +00:00
|
|
|
|
|
|
|
def delete_record(form_data, rr_items):
|
2012-10-18 10:34:22 +00:00
|
|
|
"""Delete a list of DNS records passed as strings in rr_items."""
|
|
|
|
if ("key_name" in form_data and form_data["key_name"]):
|
2011-11-26 18:03:00 +00:00
|
|
|
keyring = create_keyring(form_data["key_name"])
|
2012-10-18 10:34:22 +00:00
|
|
|
else:
|
|
|
|
keyring = None
|
2011-11-26 18:03:00 +00:00
|
|
|
|
|
|
|
dns_server = form_data["dns_server"]
|
2011-11-25 12:58:43 +00:00
|
|
|
delete_response = []
|
|
|
|
for current_rr_item in rr_items:
|
|
|
|
re_record = re.search(r"(\w+)\.(.*)$", current_rr_item)
|
|
|
|
record = re_record.group(1)
|
|
|
|
domain = re_record.group(2)
|
|
|
|
|
|
|
|
dns_update = dns.update.Update(domain, keyring = keyring)
|
|
|
|
dns_update.delete(record)
|
|
|
|
output = dns.query.tcp(dns_update, dns_server)
|
|
|
|
delete_response.append({ "rr_item" : current_rr_item, "output" : output })
|
|
|
|
|
|
|
|
return delete_response
|