1 ###############################################################################
3 # pyPDNS - A PDNS administration tool, written in pure python. #
4 # Copyright (C) 2012 IPFire development team #
6 # This program is free software: you can redistribute it and/or modify #
7 # it under the terms of the GNU General Public License as published by #
8 # the Free Software Foundation, either version 3 of the License, or #
9 # (at your option) any later version. #
11 # This program is distributed in the hope that it will be useful, #
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 # GNU General Public License for more details. #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
19 ###############################################################################
21 # Basic information about the database layout can be found here: #
22 # http://doc.powerdns.com/gsqlite.html #
24 # More details about the database tables and fields can be found here: #
25 # http://wiki.powerdns.com/trac/wiki/fields #
27 ###############################################################################
34 DB
= "/var/lib/pdns/pdns.db"
36 # Create the primary DNS class.
41 Uses the database class from imported database module.
42 Connects to the PDNS sqlite database.
44 def __init__(self
, db
):
45 # Try to connect to database or raise an exception.
47 self
.db
= database
.Database(db
)
49 except sqlite3
.OperationalError
, e
:
50 raise DatabaseException
, "Could not open database: %s" % e
54 # Get all configured domains.
55 def get_domains(self
):
57 Fetch all configured domains.
59 # Create an empty list.
62 # Add fetched domains to the previous created empty list.
63 for row
in self
.db
.query("SELECT id FROM domains"):
64 domain
= Domain(self
, row
.id)
65 domains
.append(domain
)
69 # Get a domain by it's name.
70 def get_domain(self
, name
):
72 Get a domain by a given name.
74 row
= self
.db
.get("SELECT id FROM domains WHERE name = ?", name
)
76 # Check if an id has been returned from database or return None.
80 return Domain(self
, row
.id)
83 # Create Domain class.
88 Uses query method from database module to get requested information
91 The domain is specified by it's unique database id.
93 def __init__(self
, dns
, domain_id
):
106 if self
.__data
is None:
107 self
.__data
= self
.db
.get("SELECT * FROM domains \
108 WHERE id = ?", self
.id)
113 # Determine the name of the zone by a given id.
116 return self
.data
.name
118 # Get information of the master nameserver from which the domain should
122 return self
.data
.master
124 # Fetch data of the last check from the domain.
126 def last_check(self
):
127 return self
.data
.last_check
129 # Get the type of the domain.
132 return self
.data
.type
134 # Get the last notified serial of a used master domain.
136 def notified_serial(self
):
137 return self
.data
.notified_serial
139 # Gain if a certain host is a supermaster for a certain domain name.
142 return self
.data
.account
144 # Get count of records of a zone. Return true if there is at least one
146 def has_records(self
):
147 count
= self
.db
.get("SELECT COUNT(*) AS num FROM records \
148 WHERE domain_id = ?", self
.id)
155 # Get all records from zone.
159 Get all records from the zone.
161 # Fetch records from zone and categorize them into their
162 # different record types.
163 for row
in self
.db
.query("SELECT id, type FROM records \
164 WHERE domain_id = ?", self
.id):
166 if row
.type == "SOA":
167 record
= SOARecord(self
, row
.id)
168 elif row
.type == "A":
169 record
= ARecord(self
, row
.id)
171 record
= Record(self
, row
.id)
175 # Get records by a specified type.
176 def get_records_by_type(self
, type):
178 for record
in self
.records
:
179 if record
.type == type:
180 records
.append(record
)
184 # Quick function to get the first SOA record from the domain.
187 records
= self
.get_records_by_type("SOA")
192 # Create class for domain records.
193 class Record(object):
197 It is used to get details about configured records.
198 The domain and record is's are specified by their unique database id's.
200 def __init__(self
, domain
, record_id
):
209 return self
.domain
.db
213 if self
.__data
is None:
214 self
.__data
= self
.db
.get("SELECT * FROM records \
215 WHERE id = ?", self
.id)
220 # Determine the type of the record.
223 return self
.data
.type
225 # Get the configured DNS name of the record.
228 return self
.data
.name
231 # Fetch content like the address to which the record points.
234 return self
.data
.content
236 # Get the "Time to live" for the record.
241 # Gain the configured record priority.
244 return self
.data
.prio
246 # Get the change_date.
248 def change_date(self
):
249 return self
.data
.change_date
251 # Fetch the ordername.
254 return self
.data
.ordername
256 # Gain all information about records authentication.
258 def authentication(self
):
259 return self
.data
.auth
262 # Create an own class to deal with "SOA" records.
263 class SOARecord(Record
):
266 This is an own class to deal with "SOA" records.
268 Uses splitt() to generate a list of the content string from the
271 Returns the requested entries.
273 def __init__(self
, domain
, record_id
):
274 Record
.__init
__(self
, domain
, record_id
)
276 self
.soa_attrs
= self
.content
.split()
278 # Check if the content from database is valid.
279 # (It contains all 7 required information)
280 if not len(self
.soa_attrs
) == 7:
281 raise InvalidRecordDataException
, "Your SOA record \
282 doesn't contain all required seven elements."
284 # Primary NS - the domain name of the name server that was the
285 # original source of the data.
288 return self
.soa_attrs
[0]
290 # E-mail address of the person which is responsible for this domain.
293 return self
.soa_attrs
[1]
295 # The serial which increases allways after a change on the domain has
299 return self
.soa_attrs
[2]
301 # The number of seconds between the time that a secondary name server
302 # gets a copy of the domain.
305 return self
.soa_attrs
[3]
307 # The number of seconds during the next refresh attempt if the
311 return self
.soa_attrs
[4]
313 # The number of seconds that lets the secondary name server(s) know
314 # how long they can hold the information.
317 return self
.soa_attrs
[5]
319 # The number of seconds that the records in the domain are valid.
322 return self
.soa_attrs
[6]
326 class ARecord(Record
):