create feeder function to send dns updates. forward/reverse/cname call send_dns_update.
Collapse keyutils into helper. Create single create_keyring function that decides what to create.
This commit is contained in:
parent
46a91e2fdf
commit
063d64d6c6
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
# 3rd Party
|
# 3rd Party
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
|
||||||
# App Imports
|
# App Imports
|
||||||
from models import Key
|
from models import Key
|
||||||
|
|
|
@ -1,18 +1,20 @@
|
||||||
### Binder Helpers
|
### Binder Helpers
|
||||||
|
|
||||||
# Standard Imports
|
# Standard Imports
|
||||||
from collections import OrderedDict
|
import binascii
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
|
import sys
|
||||||
|
|
||||||
# 3rd Party
|
# 3rd Party
|
||||||
import dns.query
|
import dns.query
|
||||||
import dns.reversename
|
import dns.reversename
|
||||||
import dns.update
|
|
||||||
import dns.tsig
|
import dns.tsig
|
||||||
|
import dns.tsigkeyring
|
||||||
|
import dns.update
|
||||||
|
|
||||||
# App Imports
|
# App Imports
|
||||||
from binder import exceptions, keyutils, models
|
from binder import exceptions, models
|
||||||
|
|
||||||
def add_record(dns_server, zone_name, record_name, record_type, record_data, ttl, key_name, create_reverse=False):
|
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.
|
""" Parse passed elements and determine which records to create.
|
||||||
|
@ -25,15 +27,15 @@ def add_record(dns_server, zone_name, record_name, record_type, record_data, ttl
|
||||||
String record_data (IP address)
|
String record_data (IP address)
|
||||||
Int ttl
|
Int ttl
|
||||||
String key_name (from Key model)
|
String key_name (from Key model)
|
||||||
Boolean create_reverse
|
Boolean create_reverse (Whether to create a PTR record, default False)
|
||||||
|
|
||||||
Return:
|
Return:
|
||||||
Dict containing {description, output} from record creation
|
Dict containing {description, output} from record creation
|
||||||
"""
|
"""
|
||||||
|
|
||||||
response = []
|
response = []
|
||||||
response.append({ "description" : "Forward Record Added: %s.%s" % (record_name, zone_name),
|
response.append({ "description" : "Forward Record Creation: %s.%s" % (record_name, zone_name),
|
||||||
"output" : update_record(dns_server,
|
"output" : create_update(dns_server,
|
||||||
zone_name,
|
zone_name,
|
||||||
record_name,
|
record_name,
|
||||||
record_type,
|
record_type,
|
||||||
|
@ -53,8 +55,8 @@ def add_record(dns_server, zone_name, record_name, record_type, record_data, ttl
|
||||||
# for this reverse DNS record parsing.
|
# for this reverse DNS record parsing.
|
||||||
reverse_ip = re.search(r"([0-9]+).(.*)$", reverse_ip_fqdn).group(1)
|
reverse_ip = re.search(r"([0-9]+).(.*)$", reverse_ip_fqdn).group(1)
|
||||||
reverse_domain = re.search(r"([0-9]+).(.*)$", reverse_ip_fqdn).group(2)
|
reverse_domain = re.search(r"([0-9]+).(.*)$", reverse_ip_fqdn).group(2)
|
||||||
response.append({ "description" : "Reverse Record Added: %s" % record_data,
|
response.append({ "description" : "Reverse Record Creation: %s" % record_data,
|
||||||
"output" : update_record(dns_server,
|
"output" : create_update(dns_server,
|
||||||
reverse_domain,
|
reverse_domain,
|
||||||
reverse_ip,
|
reverse_ip,
|
||||||
"PTR",
|
"PTR",
|
||||||
|
@ -67,7 +69,7 @@ def add_record(dns_server, zone_name, record_name, record_type, record_data, ttl
|
||||||
def add_cname_record(dns_server, zone_name, cname, originating_record, ttl, key_name):
|
def add_cname_record(dns_server, zone_name, cname, originating_record, ttl, key_name):
|
||||||
"""Add a Cname record."""
|
"""Add a Cname record."""
|
||||||
|
|
||||||
output = update_record(dns_server,
|
output = create_update(dns_server,
|
||||||
zone_name,
|
zone_name,
|
||||||
cname,
|
cname,
|
||||||
"CNAME",
|
"CNAME",
|
||||||
|
@ -81,12 +83,8 @@ def add_cname_record(dns_server, zone_name, cname, originating_record, ttl, key_
|
||||||
def delete_record(dns_server, rr_list, key_name):
|
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."""
|
||||||
|
|
||||||
if key_name is None:
|
|
||||||
keyring = None
|
|
||||||
else:
|
|
||||||
try:
|
try:
|
||||||
this_key = models.Key.objects.get(name=key_name)
|
keyring = create_keyring(key_name)
|
||||||
keyring = keyutils.create_keyring(this_key.name, this_key.data)
|
|
||||||
except exceptions.KeyringException, err:
|
except exceptions.KeyringException, err:
|
||||||
return([{ "description" : "Error in deletion process",
|
return([{ "description" : "Error in deletion process",
|
||||||
"output" : err }])
|
"output" : err }])
|
||||||
|
@ -98,28 +96,24 @@ def delete_record(dns_server, rr_list, key_name):
|
||||||
domain = re_record.group(2)
|
domain = re_record.group(2)
|
||||||
dns_update = dns.update.Update(domain, keyring = keyring)
|
dns_update = dns.update.Update(domain, keyring = keyring)
|
||||||
dns_update.delete(record)
|
dns_update.delete(record)
|
||||||
try:
|
output = send_dns_update(dns_update, dns_server, key_name)
|
||||||
output = dns.query.tcp(dns_update, dns_server)
|
|
||||||
except dns.tsig.PeerBadKey:
|
|
||||||
output = "The DNS server does not know about the TSIG key: %s" % key_name
|
|
||||||
|
|
||||||
delete_response.append({ "description" : "Delete Record: %s" % current_rr,
|
delete_response.append({ "description" : "Delete Record: %s" % current_rr,
|
||||||
"output" : output })
|
"output" : output })
|
||||||
|
|
||||||
return delete_response
|
return delete_response
|
||||||
|
|
||||||
def update_record(dns_server, zone_name, record_name, record_type, record_data, ttl, key_name):
|
def create_update(dns_server, zone_name, record_name, record_type, record_data, ttl, key_name):
|
||||||
""" 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. """
|
||||||
|
|
||||||
if key_name is None:
|
try:
|
||||||
keyring = None
|
keyring = create_keyring(key_name)
|
||||||
else:
|
except exceptions.KeyringException, err:
|
||||||
this_key = models.Key.objects.get(name=key_name)
|
return(err)
|
||||||
keyring = keyutils.create_keyring(this_key.name, this_key.data)
|
|
||||||
|
|
||||||
dns_update = dns.update.Update(zone_name, keyring = keyring)
|
dns_update = dns.update.Update(zone_name, keyring = keyring)
|
||||||
dns_update.replace(record_name, ttl, record_type, record_data)
|
dns_update.replace(record_name, ttl, record_type, record_data)
|
||||||
output = dns.query.tcp(dns_update, dns_server)
|
output = send_dns_update(dns_update, dns_server, key_name)
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
@ -142,3 +136,57 @@ def ip_info(host_name):
|
||||||
info.append(["Error", "Unable to resolve %s: %s" % (host_name, err)])
|
info.append(["Error", "Unable to resolve %s: %s" % (host_name, err)])
|
||||||
|
|
||||||
return info
|
return info
|
||||||
|
|
||||||
|
def send_dns_update(dns_message, dns_server, key_name):
|
||||||
|
""" Send DNS message to server and return response.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
Update dns_update
|
||||||
|
String dns_server
|
||||||
|
String key_name
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
String output
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
output = dns.query.tcp(dns_message, dns_server)
|
||||||
|
except dns.tsig.PeerBadKey:
|
||||||
|
output = ("DNS server %s is not configured for TSIG key: %s." %
|
||||||
|
(dns_server, key_name))
|
||||||
|
except dns.tsig.PeerBadSignature:
|
||||||
|
output = ("DNS server %s did like the TSIG signature we sent. Check key %s "
|
||||||
|
"for correctness." % (dns_server, key_name))
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
def create_keyring(key_name):
|
||||||
|
|
||||||
|
"""Return a tsigkeyring object from key name and key data.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key_name: String representation of Key name object
|
||||||
|
|
||||||
|
Return:
|
||||||
|
None if key_name is none.
|
||||||
|
keyring object with the key name and TSIG secret.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
KeyringException: For incorrect key data.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if key_name is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# TODO: Unittest here for key_name that does not exist
|
||||||
|
# Stick this in a try/except and catch models.Key.DoesNotExist
|
||||||
|
this_key = models.Key.objects.get(name=key_name)
|
||||||
|
|
||||||
|
try:
|
||||||
|
keyring = dns.tsigkeyring.from_text({
|
||||||
|
this_key.name : this_key.data
|
||||||
|
})
|
||||||
|
except binascii.Error, err:
|
||||||
|
raise exceptions.KeyringException("Incorrect key data. Verify key: %s. Reason: %s" % (key_name, err))
|
||||||
|
|
||||||
|
return keyring
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
import binascii
|
|
||||||
|
|
||||||
import dns.tsigkeyring
|
|
||||||
|
|
||||||
from binder import exceptions
|
|
||||||
|
|
||||||
|
|
||||||
def create_keyring(key_name, key_data):
|
|
||||||
"""Return a tsigkeyring object from key name and key data.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
key_name: String representation of key name
|
|
||||||
key_data: String representation of TSIG key hash
|
|
||||||
|
|
||||||
Return:
|
|
||||||
keyring object with the key name and TSIG secret.
|
|
||||||
"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
keyring = dns.tsigkeyring.from_text({
|
|
||||||
key_name : key_data
|
|
||||||
})
|
|
||||||
except binascii.Error, err:
|
|
||||||
raise exceptions.KeyringException("Error creating keyring. Verify correct key data for key: %s. Reason: %s" % (key_name, err))
|
|
||||||
return keyring
|
|
Loading…
Reference in New Issue