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 ###############################################################################
33 DB
= "/var/lib/pdns/pdns.db"
35 # Create the primary DNS class.
40 Uses the database class from imported database module.
41 Connects to the PDNS sqlite database.
43 def __init__(self
, db
):
44 # Try to connect to database or raise an exception.
46 self
.db
= database
.Database(db
)
48 except sqlite3
.OperationalError
, e
:
49 raise errors
.DatabaseException
, "Could not open database: %s" % e
53 # Get all configured domains.
54 def get_domains(self
):
56 Fetch all configured domains.
58 # Create an empty list.
61 # Add fetched domains to the previous created empty list.
62 for row
in self
.db
.query("SELECT id FROM domains"):
63 domain
= Domain(self
, row
.id)
64 domains
.append(domain
)
68 # Get a domain by it's name.
69 def get_domain(self
, name
):
71 Get a domain by a given name.
73 row
= self
.db
.get("SELECT id FROM domains WHERE name = ?", name
)
75 # Only do anything, if there is an existing domain.
77 domain
= Domain(self
, row
.id)
81 # Create Domain class.
86 Uses query method from database module to get requested information from domain.
87 The domain is specified by it's unique database id.
89 def __init__(self
, dns
, domain_id
):
97 # Determine the name of the zone by a given id.
100 row
= self
.db
.get("SELECT name FROM domains WHERE id = ?", self
.id)
103 # Get information of the master nameserver from which the domain should be slaved.
106 row
= self
.db
.get("SELECT master FROM domains WHERE id = ?", self
.id)
109 # Fetch data of the last check from the domain.
111 def last_check(self
):
112 row
= self
.db
.get("SELECT last_check FROM domains WHERE id = ?", self
.id)
113 return row
.last_check
115 # Get the type of the domain.
118 row
= self
.db
.get("SELECT type FROM domains WHERE id = ?", self
.id)
121 # Get the last notified serial of a used master domain.
123 def notified_serial(self
):
124 row
= self
.db
.get("SELECT notified_serial FROM domains WHERE id = ?", self
.id)
125 return row
.notified_serial
127 # Gain if a certain host is a supermaster for a certain domain name.
130 row
= self
.db
.get("SELECT account FROM domains WHERE id = ?", self
.id)
133 # Get all records from zone.
137 Get all records from the zone.
139 # Create an empty list.
142 # Fetch records from zone and categorize them into their different record types.
143 for row
in self
.db
.query("SELECT id, type FROM records WHERE domain_id = ?", self
.id):
144 if row
.type == "SOA":
145 record
= SOARecord(self
, row
.id)
146 elif row
.type == "A":
147 record
= ARecord(self
, row
.id)
149 record
= Record(self
, row
.id)
150 records
.append(record
)
154 # Get records by a specified type.
155 def get_records_by_type(self
, type):
157 for record
in self
.records
:
158 if record
.type == type:
159 records
.append(record
)
163 # Quick function to get the first SOA record from the domain.
166 records
= self
.get_records_by_type("SOA")
171 # Create class for domain records.
172 class Record(object):
176 It is used to get details about configured records.
177 The domain and record is's are specified by their unique database id's.
179 def __init__(self
, domain
, record_id
):
185 return self
.domain
.db
187 # Determine the type of the record.
190 row
= self
.db
.get("SELECT type FROM records WHERE id = ?", self
.id)
193 # Get the configured DNS name of the record.
196 row
= self
.db
.get("SELECT name FROM records WHERE id = ?", self
.id)
200 # Fetch content like the address to which the record points.
203 row
= self
.db
.get("SELECT content FROM records WHERE id = ?", self
.id)
207 # Get the "Time to live" for the record.
210 row
= self
.db
.get("SELECT ttl FROM records WHERE id = ?", self
.id)
213 # Gain the configured record priority.
216 row
= self
.db
.get("SELECT prio FROM records WHERE id = ?" , self
.id)
219 # Get the change_date.
221 def change_date(self
):
222 row
= self
.db
.get("SELECT change_date FROM records WHERE id = ?" , self
.id)
223 return row
.change_date
225 # Fetch the ordername.
228 row
= self
.db
.get("SELECT ordername FROM records WHERE id = ?" , self
.id)
231 # Gain all information about records authentication.
233 def authentication(self
):
234 row
= self
.db
.get("SELECT auth FROM records WHERE id = ?" , self
.id)
238 # Create an own class to deal with "SOA" records.
239 class SOARecord(Record
):
242 This is an own class to deal with "SOA" records.
244 Uses splitt() to generate a list of the content string from the database.
245 Returns the requested entries.
247 def __init__(self
, domain
, record_id
):
248 Record
.__init
__(self
, domain
, record_id
)
250 self
.soa_attrs
= self
.content
.split()
252 # Check if the content from database is valid (It contains all 7 required information).
253 if not len(self
.soa_attrs
) == 7:
254 raise InvalidRecordDataException
, "Your SOA record \
255 doesn't contain all required seven elements."
257 # Primary NS - the domain name of the name server that was the original source of the data.
260 return self
.soa_attrs
[0]
262 # E-mail address of the person which is responsible for this domain.
265 return self
.soa_attrs
[1]
267 # The serial which increases allways after a change on the domain has been made.
270 return self
.soa_attrs
[2]
272 # The number of seconds between the time that a secondary name server gets a copy of the domain.
275 return self
.soa_attrs
[3]
277 # The number of seconds during the next refresh attempt if the previous fails.
280 return self
.soa_attrs
[4]
282 # The number of seconds that lets the secondary name server(s) know how long they can hold the information.
285 return self
.soa_attrs
[5]
287 # The number of seconds that the records in the domain are valid.
290 return self
.soa_attrs
[6]
294 class ARecord(Record
):