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