parent
8bdec03cf1
commit
710d2cf9c2
|
@ -333,6 +333,9 @@ class AXFRDaemonInstance(object):
|
||||||
for network, instance in self.dns_networks.items():
|
for network, instance in self.dns_networks.items():
|
||||||
zone_modified = False
|
zone_modified = False
|
||||||
|
|
||||||
|
# Set up our SQL cursor
|
||||||
|
sql_curs = self.sql_conn.cursor()
|
||||||
|
|
||||||
# Set up our basic variables
|
# Set up our basic variables
|
||||||
domain = network.domain
|
domain = network.domain
|
||||||
if network.ip4_gateway != 'None':
|
if network.ip4_gateway != 'None':
|
||||||
|
@ -371,34 +374,58 @@ class AXFRDaemonInstance(object):
|
||||||
#
|
#
|
||||||
# Get the current zone from the database
|
# Get the current zone from the database
|
||||||
#
|
#
|
||||||
sql_curs = self.sql_conn.cursor()
|
try:
|
||||||
sql_curs.execute(
|
sql_curs.execute(
|
||||||
"SELECT id FROM domains WHERE name=%s",
|
"SELECT id FROM domains WHERE name=%s",
|
||||||
(domain,)
|
(domain,)
|
||||||
)
|
)
|
||||||
domain_id = sql_curs.fetchone()
|
domain_id = sql_curs.fetchone()
|
||||||
sql_curs.execute(
|
sql_curs.execute(
|
||||||
"SELECT * FROM records WHERE domain_id=%s",
|
"SELECT * FROM records WHERE domain_id=%s",
|
||||||
(domain_id,)
|
(domain_id,)
|
||||||
)
|
)
|
||||||
results = list(sql_curs.fetchall())
|
results = list(sql_curs.fetchall())
|
||||||
|
if self.config['debug']:
|
||||||
|
print('SQL query results: {}'.format(results))
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.out('ERROR: Failed to obtain DNS records from database: {}'.format(e))
|
||||||
|
|
||||||
# Fix the formatting because it's useless for comparison
|
# Fix the formatting because it's useless for comparison
|
||||||
# reference: ((10, 28, 'testnet01.i.bonilan.net', 'SOA', 'nsX.pvc.local root.pvc.local 1 10800 1800 86400 86400', 86400, 0, None, 0, None, 1), etc.)
|
# reference: ((10, 28, 'testnet01.i.bonilan.net', 'SOA', 'nsX.pvc.local root.pvc.local 1 10800 1800 86400 86400', 86400, 0, None, 0, None, 1), etc.)
|
||||||
records_old = list()
|
records_old = list()
|
||||||
records_old_ids = list()
|
records_old_ids = list()
|
||||||
|
if not results:
|
||||||
|
if self.config['debug']:
|
||||||
|
print('No results found, skipping.')
|
||||||
|
continue
|
||||||
for record in results:
|
for record in results:
|
||||||
# Skip the non-A
|
# Skip the non-A
|
||||||
if record[3] != 'A' or record[3] != 'AAAA':
|
r_id = record[0]
|
||||||
continue
|
r_name = record[2]
|
||||||
|
r_ttl = record[5]
|
||||||
|
r_type = record[3]
|
||||||
|
r_data = record[4]
|
||||||
# Assemble a list element in the same format as the AXFR data
|
# Assemble a list element in the same format as the AXFR data
|
||||||
entry = '{} {} IN {} {}'.format(record[2], record[5], record[3], record[4])
|
entry = '{} {} IN {} {}'.format(r_name, r_ttl, r_type, r_data)
|
||||||
|
if self.config['debug']:
|
||||||
|
print('Found record: {}'.format(entry))
|
||||||
|
|
||||||
|
# Skip non-A or AAAA records
|
||||||
|
if r_type != 'A' and r_type != 'AAAA':
|
||||||
|
if self.config['debug']:
|
||||||
|
print('Skipping record {}, not A or AAAA: "{}"'.format(entry, r_type))
|
||||||
|
continue
|
||||||
|
|
||||||
records_old.append(entry)
|
records_old.append(entry)
|
||||||
records_old_ids.append(record[0])
|
records_old_ids.append(r_id)
|
||||||
|
|
||||||
records_new.sort()
|
records_new.sort()
|
||||||
records_old.sort()
|
records_old.sort()
|
||||||
|
|
||||||
|
if self.config['debug']:
|
||||||
|
print('New: {}'.format(records_new))
|
||||||
|
print('Old: {}'.format(records_old))
|
||||||
|
|
||||||
# Find the differences between the lists
|
# Find the differences between the lists
|
||||||
# Basic check one: are they completely equal
|
# Basic check one: are they completely equal
|
||||||
if records_new != records_old:
|
if records_new != records_old:
|
||||||
|
@ -408,6 +435,10 @@ class AXFRDaemonInstance(object):
|
||||||
in_new_not_in_old = in_new - in_old
|
in_new_not_in_old = in_new - in_old
|
||||||
in_old_not_in_new = in_old - in_new
|
in_old_not_in_new = in_old - in_new
|
||||||
|
|
||||||
|
if self.config['debug']:
|
||||||
|
print('New but not old: {}'.format(in_new_not_in_old))
|
||||||
|
print('Old but not new: {}'.format(in_old_not_in_new))
|
||||||
|
|
||||||
# Go through the old list
|
# Go through the old list
|
||||||
remove_records = list() # list of database IDs
|
remove_records = list() # list of database IDs
|
||||||
for i in range(len(records_old)):
|
for i in range(len(records_old)):
|
||||||
|
@ -430,7 +461,8 @@ class AXFRDaemonInstance(object):
|
||||||
if len(remove_records) > 0:
|
if len(remove_records) > 0:
|
||||||
# Remove the invalid old records
|
# Remove the invalid old records
|
||||||
for record_id in remove_records:
|
for record_id in remove_records:
|
||||||
sql_curs = self.sql_conn.cursor()
|
if self.config['debug']:
|
||||||
|
print('Removing record: {}'.format(record_id))
|
||||||
sql_curs.execute(
|
sql_curs.execute(
|
||||||
"DELETE FROM records WHERE id=%s",
|
"DELETE FROM records WHERE id=%s",
|
||||||
(record_id,)
|
(record_id,)
|
||||||
|
@ -442,14 +474,15 @@ class AXFRDaemonInstance(object):
|
||||||
for record in in_new_not_in_old:
|
for record in in_new_not_in_old:
|
||||||
# [NAME, TTL, 'IN', TYPE, DATA]
|
# [NAME, TTL, 'IN', TYPE, DATA]
|
||||||
record = record.split()
|
record = record.split()
|
||||||
rname = record[0]
|
r_name = record[0]
|
||||||
rttl = record[1]
|
r_ttl = record[1]
|
||||||
rtype = record[3]
|
r_type = record[3]
|
||||||
rdata = record[4]
|
r_data = record[4]
|
||||||
sql_curs = self.sql_conn.cursor()
|
if self.config['debug']:
|
||||||
|
print('Add record: {}'.format(name))
|
||||||
sql_curs.execute(
|
sql_curs.execute(
|
||||||
"INSERT INTO records (domain_id, name, ttl, type, prio, content) VALUES (%s, %s, %s, %s, %s, %s)",
|
"INSERT INTO records (domain_id, name, ttl, type, prio, content) VALUES (%s, %s, %s, %s, %s, %s)",
|
||||||
(domain_id, rname, rttl, rtype, 0, rdata)
|
(domain_id, r_name, r_ttl, r_type, 0, r_data)
|
||||||
)
|
)
|
||||||
changed = True
|
changed = True
|
||||||
|
|
||||||
|
@ -463,13 +496,20 @@ class AXFRDaemonInstance(object):
|
||||||
current_serial = int(soa_record[2])
|
current_serial = int(soa_record[2])
|
||||||
new_serial = current_serial + 1
|
new_serial = current_serial + 1
|
||||||
soa_record[2] = str(new_serial)
|
soa_record[2] = str(new_serial)
|
||||||
|
if self.config['debug']:
|
||||||
|
print('Records changed; bumping SOA: {}'.format(new_serial))
|
||||||
sql_curs.execute(
|
sql_curs.execute(
|
||||||
"UPDATE records SET content=%s WHERE domain_id=%s AND type='SOA'",
|
"UPDATE records SET content=%s WHERE domain_id=%s AND type='SOA'",
|
||||||
(' '.join(soa_record), domain_id)
|
(' '.join(soa_record), domain_id)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Commit all the previous changes
|
# Commit all the previous changes
|
||||||
self.sql_conn.commit()
|
if self.config['debug']:
|
||||||
|
print('Committing database changes and reloading PDNS')
|
||||||
|
try:
|
||||||
|
self.sql_conn.commit()
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.out('ERROR: Failed to commit DNS aggregator changes: {}'.format(e), state='e')
|
||||||
|
|
||||||
# Reload the domain
|
# Reload the domain
|
||||||
common.run_os_command(
|
common.run_os_command(
|
||||||
|
|
Loading…
Reference in New Issue