--- /dev/null
+###############################################################################
+# #
+# pyPDNS - A PDNS administration tool, written in pure python. #
+# Copyright (C) 2012 Pakfire development team #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+# #
+###############################################################################
+# #
+# More details about the database tables and fields can be found here: #
+# http://wiki.powerdns.com/trac/wiki/fields #
+# #
+###############################################################################
+
+import database
+
+DB = "/var/lib/pdns/pdns.db"
+
+# Create the primary DNS class.
+"""Use Database class from imported database module to connect to the PDNS sqlite database."""
+class DNS(object):
+ def __init__(self, db):
+ self.db = database.Database(db)
+
+ # Get all configured domains.
+ def get_domains(self):
+ domains = []
+
+ """Fetch all configured domains, line by line and add them to the previous created empty list."""
+ for row in self.db.query("SELECT id FROM domains"):
+ domain = Domain(self, row.id)
+ domains.append(domain)
+
+ return domains
+
+ # Get a domain by it's name.
+ def get_domain(self, name):
+ row = self.db.get("SELECT id FROM domains WHERE name = ?", name)
+ domain = Domain(self, row.id)
+
+ return domain
+
+# Create Domain class.
+"""Use query method from database module to get all requested information about our domain."""
+"""The domain is specified by it's unique id."""
+class Domain(object):
+ def __init__(self, dns, domain_id):
+ self.dns = dns
+ self.id = domain_id
+
+ @property
+ def db(self):
+ return self.dns.db
+
+ # Determine the name of the zone by a given id.
+ @property
+ def name(self):
+ row = self.db.get("SELECT name FROM domains WHERE id = ?", self.id)
+ return row.name
+
+ # Get information of the master nameserver from which the domain should be slaved.
+ @property
+ def master(self):
+ row = self.db.get("SELECT master FROM domains WHERE id = ?", self.id)
+ return row.master
+
+ # Fetch data of the last check from the domain.
+ @property
+ def last_check(self):
+ row = self.db.get("SELECT last_check FROM domains WHERE id = ?", self.id)
+ return row.last_check
+
+ # Get the type of the domain.
+ @property
+ def type(self):
+ row = self.db.get("SELECT type FROM domains WHERE id = ?", self.id)
+ return row.type
+
+ # Get the last notified serial of a used master domain.
+ @property
+ def notified_serial(self):
+ row = self.db.get("SELECT notified_serial FROM domains WHERE id = ?", self.id)
+ return row.notified_serial
+
+ # Gain if a certain host is a supermaster for a certain domain name.
+ @property
+ def account(self):
+ row = self.db.get("SELECT account FROM domains WHERE id = ?", self.id)
+ return row.account
+
+ # Get all records from zone.
+ @property
+ def records(self):
+ records = []
+
+ """Fetch all records from domain, line by line and add them to the previous created empty list."""
+ for row in self.db.query("SELECT id FROM records WHERE domain_id = ?", self.id):
+ record = Record(self, row.id)
+ records.append(record)
+
+ return records
+
+
+
+# Create class for domain records.
+"""It is used to get more details about the configured records."""
+"""The domain is specified by it's unique id."""
+class Record(object):
+ def __init__(self, domain, record_id):
+ self.domain = domain
+ self.id = record_id
+
+ @property
+ def db(self):
+ return self.domain.db
+
+ # Determine the type of the record.
+ @property
+ def type(self):
+ row = self.db.get("SELECT type FROM records WHERE id = ?", self.id)
+ return row.type
+
+ # Get the configured DNS name of the record.
+ @property
+ def dnsname(self):
+ row = self.db.get("SELECT name FROM records WHERE id = ?", self.id)
+ return row.name
+
+
+ # Fetch content like the address to which the record points.
+ @property
+ def content(self):
+ row = self.db.get("SELECT content FROM records WHERE id = ?", self.id)
+ return row.content
+
+
+ # Get the "Time to live" for the record.
+ @property
+ def ttl(self):
+ row = self.db.get("SELECT ttl FROM records WHERE id = ?", self.id)
+ return row.ttl
+
+ # Gain the configured record priority.
+ @property
+ def priority(self):
+ row = self.db.get("SELECT prio FROM records WHERE id = ?" , self.id)
+ return row.prio
+
+ # Get the change_date.
+ @property
+ def change_date(self):
+ row = self.db.get("SELECT change_date FROM records WHERE id = ?" , self.id)
+ return row.change_date
+
+ # Fetch the ordername.
+ @property
+ def ordername(self):
+ row = self.db.get("SELECT ordername FROM records WHERE id = ?" , self.id)
+ return row.ordername
+
+ # Gain all information about records authification.
+ @property
+ def authification(self):
+ row = self.db.get("SELECT auth FROM records WHERE id = ?" , self.id)
+ return row.auth
--- /dev/null
+#!/usr/bin/python\r
+\r
+import itertools\r
+import logging\r
+import os\r
+import sqlite3\r
+\r
+class Row(dict):\r
+ """A dict that allows for object-like property access syntax."""\r
+ def __getattr__(self, name):\r
+ try:\r
+ return self[name]\r
+ except KeyError:\r
+ raise AttributeError(name)\r
+\r
+\r
+class Database(object):\r
+ def __init__(self, filename):\r
+ self.filename = filename\r
+\r
+ self._db = None\r
+\r
+ try:\r
+ self.reconnect()\r
+ except:\r
+ logging.error("Cannot connect to database on %s", self.filename, exc_info=True)\r
+\r
+ def __del__(self):\r
+ self.close()\r
+\r
+ def close(self):\r
+ """Closes this database connection."""\r
+ if self._db is not None:\r
+ self._db.commit()\r
+ self._db.close()\r
+ self._db = None\r
+\r
+ def reconnect(self):\r
+ """Closes the existing database connection and re-opens it."""\r
+ self.close()\r
+ self._db = sqlite3.connect(self.filename)\r
+ self._db.isolation_level = None # Enabled autocommit mode\r
+\r
+ def query(self, query, *parameters):\r
+ """Returns a row list for the given query and parameters."""\r
+ cursor = self._cursor()\r
+ try:\r
+ self._execute(cursor, query, parameters)\r
+ column_names = [d[0] for d in cursor.description]\r
+ return [Row(itertools.izip(column_names, row)) for row in cursor]\r
+ finally:\r
+ #cursor.close()\r
+ pass\r
+\r
+ def get(self, query, *parameters):\r
+ """Returns the first row returned for the given query."""\r
+ rows = self.query(query, *parameters)\r
+ if not rows:\r
+ return None\r
+ elif len(rows) > 1:\r
+ raise Exception("Multiple rows returned for Database.get() query")\r
+ else:\r
+ return rows[0]\r
+\r
+ def execute(self, query, *parameters):\r
+ """Executes the given query, returning the lastrowid from the query."""\r
+ cursor = self._cursor()\r
+ try:\r
+ self._execute(cursor, query, parameters)\r
+ return cursor.lastrowid\r
+ finally:\r
+ pass\r
+ #self._db.commit()\r
+ #cursor.close()\r
+\r
+ def _cursor(self):\r
+ if self._db is None: \r
+ self.reconnect()\r
+ return self._db.cursor()\r
+\r
+ def _execute(self, cursor, query, parameters):\r
+ try:\r
+ return cursor.execute(query, parameters)\r
+ except sqlite3.OperationalError:\r
+ logging.error("Error connecting to database on %s", self.filename)\r
+ self.close()\r
+ raise\r