|
@@ -25,24 +25,25 @@ RR_NAME_INDEX = 2
|
|
|
RR_TTL_INDEX = 4
|
|
|
RR_RDATA_INDEX = 7
|
|
|
|
|
|
+#########################################################################
|
|
|
+# define exceptions
|
|
|
+#########################################################################
|
|
|
class Sqlite3DSError(Exception):
|
|
|
- """ Define exceptions."""
|
|
|
pass
|
|
|
|
|
|
+#########################################################################
|
|
|
+# create: set up schema for a newly created zones/records database
|
|
|
+#########################################################################
|
|
|
def create(cur):
|
|
|
- """ Set up schema for a newly created zones/records database.
|
|
|
-
|
|
|
- Arguments:
|
|
|
- cur - sqlite3 cursor.
|
|
|
- """
|
|
|
+ """Create new zone database"""
|
|
|
cur.execute("CREATE TABLE schema_version (version INTEGER NOT NULL)")
|
|
|
cur.execute("INSERT INTO schema_version VALUES (1)")
|
|
|
- cur.execute("""CREATE TABLE zones (id INTEGER PRIMARY KEY,
|
|
|
+ cur.execute("""CREATE TABLE zones (id INTEGER PRIMARY KEY,
|
|
|
name STRING NOT NULL COLLATE NOCASE,
|
|
|
- rdclass STRING NOT NULL COLLATE NOCASE DEFAULT 'IN',
|
|
|
+ rdclass STRING NOT NULL COLLATE NOCASE DEFAULT 'IN',
|
|
|
dnssec BOOLEAN NOT NULL DEFAULT 0)""")
|
|
|
cur.execute("CREATE INDEX zones_byname ON zones (name)")
|
|
|
- cur.execute("""CREATE TABLE records (id INTEGER PRIMARY KEY,
|
|
|
+ cur.execute("""CREATE TABLE records (id INTEGER PRIMARY KEY,
|
|
|
zone_id INTEGER NOT NULL,
|
|
|
name STRING NOT NULL COLLATE NOCASE,
|
|
|
rname STRING NOT NULL COLLATE NOCASE,
|
|
@@ -52,7 +53,7 @@ def create(cur):
|
|
|
rdata STRING NOT NULL)""")
|
|
|
cur.execute("CREATE INDEX records_byname ON records (name)")
|
|
|
cur.execute("CREATE INDEX records_byrname ON records (rname)")
|
|
|
- cur.execute("""CREATE TABLE nsec3 (id INTEGER PRIMARY KEY,
|
|
|
+ cur.execute("""CREATE TABLE nsec3 (id INTEGER PRIMARY KEY,
|
|
|
zone_id INTEGER NOT NULL,
|
|
|
hash STRING NOT NULL COLLATE NOCASE,
|
|
|
owner STRING NOT NULL COLLATE NOCASE,
|
|
@@ -61,17 +62,17 @@ def create(cur):
|
|
|
rdata STRING NOT NULL)""")
|
|
|
cur.execute("CREATE INDEX nsec3_byhash ON nsec3 (hash)")
|
|
|
|
|
|
+#########################################################################
|
|
|
+# open: open a database. if the database is not yet set up,
|
|
|
+# call create to do so.
|
|
|
+# input:
|
|
|
+# dbfile - the filename for the sqlite3 database
|
|
|
+# returns:
|
|
|
+# sqlite3 connection, sqlite3 cursor
|
|
|
+#########################################################################
|
|
|
def open(dbfile):
|
|
|
- """ Open a database, if the database is not yet set up, call create
|
|
|
- to do so. It may raise Sqlite3DSError if failed to open sqlite3
|
|
|
- database file or find bad database schema version in the database.
|
|
|
-
|
|
|
- Arguments:
|
|
|
- dbfile - the filename for the sqlite3 database.
|
|
|
-
|
|
|
- Return sqlite3 connection, sqlite3 cursor.
|
|
|
- """
|
|
|
- try:
|
|
|
+ """Open the database file. If necessary, set it up"""
|
|
|
+ try:
|
|
|
conn = sqlite3.connect(dbfile)
|
|
|
cur = conn.cursor()
|
|
|
except Exception as e:
|
|
@@ -92,15 +93,12 @@ def open(dbfile):
|
|
|
|
|
|
return conn, cur
|
|
|
|
|
|
-
|
|
|
+#########################################################################
|
|
|
+# get_zone_datas
|
|
|
+# a generator function producing an iterable set of
|
|
|
+# the records in the zone with the given zone name.
|
|
|
+#########################################################################
|
|
|
def get_zone_datas(zonename, dbfile):
|
|
|
- """ A generator function producing an iterable set of
|
|
|
- the records in the zone with the given zone name.
|
|
|
-
|
|
|
- Arguments:
|
|
|
- zonename - the zone's origin name.
|
|
|
- dbfile - the filename for the sqlite3 database.
|
|
|
- """
|
|
|
conn, cur = open(dbfile)
|
|
|
zone_id = get_zoneid(zonename, cur)
|
|
|
|
|
@@ -114,14 +112,12 @@ def get_zone_datas(zonename, dbfile):
|
|
|
conn.close()
|
|
|
|
|
|
|
|
|
+#########################################################################
|
|
|
+# get_zone_soa
|
|
|
+# returns the soa record of the zone with the given zone name.
|
|
|
+# If the zone doesn't exist, return None.
|
|
|
+#########################################################################
|
|
|
def get_zone_soa(zonename, dbfile):
|
|
|
- """Return the soa record of the zone with the given zone name.
|
|
|
- If the zone doesn't exist, return None.
|
|
|
-
|
|
|
- Arguments:
|
|
|
- zonename - the zone's origin name.
|
|
|
- dbfile - the filename for the sqlite3 database.
|
|
|
- """
|
|
|
conn, cur = open(dbfile)
|
|
|
id = get_zoneid(zonename, cur)
|
|
|
cur.execute("SELECT * FROM records WHERE zone_id = ? and rdtype = ?", [id, 'SOA'])
|
|
@@ -132,20 +128,16 @@ def get_zone_soa(zonename, dbfile):
|
|
|
return datas
|
|
|
|
|
|
|
|
|
+#########################################################################
|
|
|
+# get_zone_rrset
|
|
|
+# returns the rrset of the zone with the given zone name, rrset name
|
|
|
+# and given rd type.
|
|
|
+# If the zone doesn't exist or rd type doesn't exist, return an empty list.
|
|
|
+#########################################################################
|
|
|
def get_zone_rrset(zonename, rr_name, rdtype, dbfile):
|
|
|
- """Return the rrset of the zone with the given zone name, rrset
|
|
|
- name and given RR type. If the zone doesn't exist or RR type
|
|
|
- doesn't exist, return an empty list.
|
|
|
-
|
|
|
- Arguments:
|
|
|
- zonename - the zone's origin name.
|
|
|
- rr_name - rr name.
|
|
|
- rdtype - RR type.
|
|
|
- dbfile - the filename for the sqlite3 database.
|
|
|
- """
|
|
|
conn, cur = open(dbfile)
|
|
|
id = get_zoneid(zonename, cur)
|
|
|
- cur.execute("SELECT * FROM records WHERE name = ? and zone_id = ? and rdtype = ?",
|
|
|
+ cur.execute("SELECT * FROM records WHERE name = ? and zone_id = ? and rdtype = ?",
|
|
|
[rr_name, id, rdtype])
|
|
|
datas = cur.fetchall()
|
|
|
cur.close()
|
|
@@ -153,13 +145,12 @@ def get_zone_rrset(zonename, rr_name, rdtype, dbfile):
|
|
|
return datas
|
|
|
|
|
|
|
|
|
-def get_zones_info(dbfile):
|
|
|
- """ Return all the zones' information in the database.
|
|
|
-
|
|
|
- Arguments:
|
|
|
- dbfile - the filename for the sqlite3 database.
|
|
|
- """
|
|
|
- conn, cur = open(dbfile)
|
|
|
+#########################################################################
|
|
|
+# get_zones_info:
|
|
|
+# returns all the zones' information.
|
|
|
+#########################################################################
|
|
|
+def get_zones_info(db_file):
|
|
|
+ conn, cur = open(db_file)
|
|
|
cur.execute("SELECT name, rdclass FROM zones")
|
|
|
info = cur.fetchone()
|
|
|
while info:
|
|
@@ -169,69 +160,44 @@ def get_zones_info(dbfile):
|
|
|
cur.close()
|
|
|
conn.close()
|
|
|
|
|
|
-
|
|
|
-def get_zoneid(zonename, cur):
|
|
|
- """ Get the zone_id for a given zone name.
|
|
|
-
|
|
|
- Arguments:
|
|
|
- zonename - the zone's origin name.
|
|
|
- cur - sqlite3 cursor.
|
|
|
-
|
|
|
- Return zone id for the given zone name, or an empty string if the
|
|
|
- zone is not found.
|
|
|
- """
|
|
|
- cur.execute("SELECT id FROM zones WHERE name = ?", [zonename])
|
|
|
+#########################################################################
|
|
|
+# get_zoneid:
|
|
|
+# returns the zone_id for a given zone name, or an empty
|
|
|
+# string if the zone is not found
|
|
|
+#########################################################################
|
|
|
+def get_zoneid(zone, cur):
|
|
|
+ cur.execute("SELECT id FROM zones WHERE name = ?", [zone])
|
|
|
row = cur.fetchone()
|
|
|
if row:
|
|
|
return row[0]
|
|
|
else:
|
|
|
return ''
|
|
|
-
|
|
|
-
|
|
|
-def zone_exist(zonename, dbfile):
|
|
|
- """ Search for the zone with the given zone name in databse. This
|
|
|
- method may throw a Sqlite3DSError exception because its underlying
|
|
|
- method open() can throw that exception.
|
|
|
-
|
|
|
- Arguments:
|
|
|
- zonename - the zone's origin name.
|
|
|
- dbfile - the filename for the sqlite3 database.
|
|
|
-
|
|
|
- Return True if the zone is found, otherwise False.
|
|
|
- """
|
|
|
- conn, cur = open(dbfile)
|
|
|
- zoneid = get_zoneid(zonename, cur)
|
|
|
- cur.close()
|
|
|
- conn.close()
|
|
|
- if zoneid:
|
|
|
- return True
|
|
|
- return False
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
+#########################################################################
|
|
|
+# reverse_name:
|
|
|
+# reverse the labels of a DNS name. (for example,
|
|
|
+# "bind10.isc.org." would become "org.isc.bind10.")
|
|
|
+#########################################################################
|
|
|
def reverse_name(name):
|
|
|
"""Reverse the labels of a domain name; for example,
|
|
|
- given 'www.example.org.', return 'org.example.www.' This is needed
|
|
|
- for DNSSEC sort order.
|
|
|
-
|
|
|
- Arguments:
|
|
|
- name - the DNS name will be reversed.
|
|
|
- """
|
|
|
+ given 'www.isc.org.', return 'org.isc.www.' This is needed
|
|
|
+ for DNSSEC sort order."""
|
|
|
new = name.split('.')
|
|
|
new.reverse()
|
|
|
if new[0] == '':
|
|
|
new.pop(0)
|
|
|
return '.'.join(new)+'.'
|
|
|
|
|
|
-
|
|
|
+#########################################################################
|
|
|
+# load:
|
|
|
+# load a zone into the SQL database.
|
|
|
+# input:
|
|
|
+# dbfile: the sqlite3 database fileanme
|
|
|
+# zone: the zone origin
|
|
|
+# reader: a generator function producing an iterable set of
|
|
|
+# name/ttl/class/rrtype/rdata-text tuples
|
|
|
+#########################################################################
|
|
|
def load(dbfile, zone, reader):
|
|
|
- """ Load a zone into the SQL database.
|
|
|
-
|
|
|
- Arguments:
|
|
|
- dbfile - the sqlite3 database filename
|
|
|
- zone - the zone origin
|
|
|
- reader - a generator function producing an iterable set of
|
|
|
- name/ttl/class/rrtype/rdata-text tuples.
|
|
|
- """
|
|
|
# if the zone name doesn't contain the trailing dot, automatically add it.
|
|
|
if zone[-1] != '.':
|
|
|
zone += '.'
|