]> git.ipfire.org Git - people/stevee/pypdns.git/blame - backend.py
Add exceptions for database handling and invalid SOA records.
[people/stevee/pypdns.git] / backend.py
CommitLineData
1336cd4e
SS
1###############################################################################
2# #
3# pyPDNS - A PDNS administration tool, written in pure python. #
9deb9e05 4# Copyright (C) 2012 IPFire development team #
1336cd4e
SS
5# #
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. #
10# #
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. #
15# #
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/>. #
18# #
19###############################################################################
20# #
a8b3a646
SS
21# Basic information about the database layout can be found here: #
22# http://doc.powerdns.com/gsqlite.html #
23# #
1336cd4e
SS
24# More details about the database tables and fields can be found here: #
25# http://wiki.powerdns.com/trac/wiki/fields #
26# #
27###############################################################################
28
29import database
a7ceb5de
SS
30import errors
31import sqlite3
1336cd4e
SS
32
33DB = "/var/lib/pdns/pdns.db"
34
35# Create the primary DNS class.
1336cd4e 36class DNS(object):
a7ceb5de
SS
37 """
38 Primary DNS class.
259f19af 39
a7ceb5de
SS
40 Uses the database class from imported database module.
41 Connects to the PDNS sqlite database.
42 """
1336cd4e 43 def __init__(self, db):
a7ceb5de
SS
44 # Try to connect to database or raise an exception.
45 try:
46 self.db = database.Database(db)
47
48 except sqlite3.OperationalError, e:
49 raise errors.DatabaseException, "Could not open database: %s" % e
50
51
1336cd4e
SS
52
53 # Get all configured domains.
54 def get_domains(self):
259f19af
SS
55 """
56 Fetch all configured domains.
57 """
58 # Create an empty list.
1336cd4e
SS
59 domains = []
60
259f19af 61 # Add fetched domains to the previous created empty list.
1336cd4e
SS
62 for row in self.db.query("SELECT id FROM domains"):
63 domain = Domain(self, row.id)
64 domains.append(domain)
65
66 return domains
67
68 # Get a domain by it's name.
69 def get_domain(self, name):
259f19af
SS
70 """
71 Get a domain by a given name.
72 """
1336cd4e 73 row = self.db.get("SELECT id FROM domains WHERE name = ?", name)
1336cd4e 74
d267bece
SS
75 # Only do anything, if there is an existing domain.
76 if row:
77 domain = Domain(self, row.id)
78
79 return domain
1336cd4e
SS
80
81# Create Domain class.
1336cd4e 82class Domain(object):
a7ceb5de
SS
83 """
84 Domain class.
259f19af 85
a7ceb5de
SS
86 Uses query method from database module to get requested information from domain.
87 The domain is specified by it's unique database id.
88 """
1336cd4e
SS
89 def __init__(self, dns, domain_id):
90 self.dns = dns
91 self.id = domain_id
92
93 @property
94 def db(self):
95 return self.dns.db
96
97 # Determine the name of the zone by a given id.
98 @property
99 def name(self):
100 row = self.db.get("SELECT name FROM domains WHERE id = ?", self.id)
101 return row.name
102
103 # Get information of the master nameserver from which the domain should be slaved.
104 @property
105 def master(self):
106 row = self.db.get("SELECT master FROM domains WHERE id = ?", self.id)
107 return row.master
108
109 # Fetch data of the last check from the domain.
110 @property
111 def last_check(self):
112 row = self.db.get("SELECT last_check FROM domains WHERE id = ?", self.id)
113 return row.last_check
114
115 # Get the type of the domain.
116 @property
117 def type(self):
118 row = self.db.get("SELECT type FROM domains WHERE id = ?", self.id)
119 return row.type
120
121 # Get the last notified serial of a used master domain.
122 @property
123 def notified_serial(self):
124 row = self.db.get("SELECT notified_serial FROM domains WHERE id = ?", self.id)
125 return row.notified_serial
126
127 # Gain if a certain host is a supermaster for a certain domain name.
128 @property
129 def account(self):
130 row = self.db.get("SELECT account FROM domains WHERE id = ?", self.id)
131 return row.account
132
133 # Get all records from zone.
134 @property
135 def records(self):
259f19af
SS
136 """
137 Get all records from the zone.
138 """
139 # Create an empty list.
1336cd4e
SS
140 records = []
141
259f19af 142 # Fetch records from zone and categorize them into their different record types.
abccf64a
SS
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)
148 else:
149 record = Record(self, row.id)
1336cd4e
SS
150 records.append(record)
151
152 return records
153
abccf64a
SS
154 # Get records by a specified type.
155 def get_records_by_type(self, type):
156 records = []
157 for record in self.records:
158 if record.type == type:
159 records.append(record)
160
161 return records
162
163 # Quick function to get the first SOA record from the domain.
164 @property
165 def SOA(self):
166 records = self.get_records_by_type("SOA")
167 if records:
168 return records[0]
1336cd4e
SS
169
170
171# Create class for domain records.
1336cd4e 172class Record(object):
a7ceb5de
SS
173 """
174 Record class
259f19af 175
a7ceb5de
SS
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.
178 """
1336cd4e
SS
179 def __init__(self, domain, record_id):
180 self.domain = domain
181 self.id = record_id
182
183 @property
184 def db(self):
185 return self.domain.db
186
187 # Determine the type of the record.
188 @property
189 def type(self):
190 row = self.db.get("SELECT type FROM records WHERE id = ?", self.id)
191 return row.type
192
193 # Get the configured DNS name of the record.
194 @property
195 def dnsname(self):
196 row = self.db.get("SELECT name FROM records WHERE id = ?", self.id)
197 return row.name
198
199
200 # Fetch content like the address to which the record points.
201 @property
202 def content(self):
203 row = self.db.get("SELECT content FROM records WHERE id = ?", self.id)
204 return row.content
205
206
207 # Get the "Time to live" for the record.
208 @property
209 def ttl(self):
210 row = self.db.get("SELECT ttl FROM records WHERE id = ?", self.id)
211 return row.ttl
212
213 # Gain the configured record priority.
214 @property
215 def priority(self):
216 row = self.db.get("SELECT prio FROM records WHERE id = ?" , self.id)
217 return row.prio
218
219 # Get the change_date.
220 @property
221 def change_date(self):
222 row = self.db.get("SELECT change_date FROM records WHERE id = ?" , self.id)
223 return row.change_date
224
225 # Fetch the ordername.
226 @property
227 def ordername(self):
228 row = self.db.get("SELECT ordername FROM records WHERE id = ?" , self.id)
229 return row.ordername
230
abccf64a 231 # Gain all information about records authentication.
1336cd4e 232 @property
abccf64a 233 def authentication(self):
1336cd4e
SS
234 row = self.db.get("SELECT auth FROM records WHERE id = ?" , self.id)
235 return row.auth
abccf64a
SS
236
237
238# Create an own class to deal with "SOA" records.
abccf64a 239class SOARecord(Record):
a7ceb5de
SS
240 """
241 SOA Record class.
242 This is an own class to deal with "SOA" records.
259f19af 243
a7ceb5de
SS
244 Uses splitt() to generate a list of the content string from the database.
245 Returns the requested entries.
246 """
abccf64a
SS
247 def __init__(self, domain, record_id):
248 Record.__init__(self, domain, record_id)
249
250 self.soa_attrs = self.content.split()
251
252 # Check if the content from database is valid (It contains all 7 required information).
253 if not len(self.soa_attrs) == 7:
a7ceb5de
SS
254 raise InvalidRecordDataException, "Your SOA record \
255 doesn't contain all required seven elements."
abccf64a
SS
256
257 # Primary NS - the domain name of the name server that was the original source of the data.
258 @property
259 def mname(self):
260 return self.soa_attrs[0]
261
262 # E-mail address of the person which is responsible for this domain.
263 @property
264 def email(self):
265 return self.soa_attrs[1]
266
267 # The serial which increases allways after a change on the domain has been made.
268 @property
269 def serial(self):
270 return self.soa_attrs[2]
271
272 # The number of seconds between the time that a secondary name server gets a copy of the domain.
273 @property
274 def refresh(self):
275 return self.soa_attrs[3]
276
277 # The number of seconds during the next refresh attempt if the previous fails.
278 @property
279 def retry(self):
280 return self.soa_attrs[4]
281
282 # The number of seconds that lets the secondary name server(s) know how long they can hold the information.
283 @property
284 def expire(self):
285 return self.soa_attrs[5]
286
287 # The number of seconds that the records in the domain are valid.
288 @property
289 def minimum(self):
290 return self.soa_attrs[6]
291
292
293
294class ARecord(Record):
295 pass