def editName(self, fromName, toName): data = {} if fromName == toName: data["error"] = u"Name entry is the same as existing name" data["success"] = False return data db = DBHandler(app.config["DBFILE"]) c = db.getCursor() if db.exists("zones", "name", toName): data["error"] = u"Duplicate name entry in db" data["success"] = False return data if not db.exists("zones", "name", fromName): data["error"] = u"No old name entry in db" data["success"] = False return data try: c.execute( """ UPDATE zones SET old_value = name, name = ?, updated = 1, update_type = 'MODIFIED NAME' WHERE name LIKE ? """, [toName, fromName]) db.commit() data["success"] = True data["message"] = u"Entry %s updated from %s" % (toName, fromName) except Exception, e: errormsg = u"Unsuccessful database update transaction:" + str(e) log.exception(errormsg, self.__class__.__name__) data["success"] = False data["error"] = errormsg
def editHost(self, name, host): data = {} db = DBHandler(app.config["DBFILE"]) c = db.getCursor() dbdata = list( c.execute( """ SELECT host FROM zones WHERE name LIKE ? """, [name])) if len(dbdata) == 0: data["error"] = u"Zone doesn't exist" data["success"] = False return data else: zone = dbdata[0] if zone[0] == host: data["error"] = u"Host entry is the same as existing name" data["success"] = False return data try: c.execute( """ UPDATE zones SET host = ?, updated = 1, update_type = 'MODIFIED HOST' WHERE name LIKE ? """, [host, name]) db.commit() data["success"] = True data["message"] = u"Entry %s updated from %s" % (host, zone[0]) except Exception, e: errormsg = u"Unsuccessful database update transaction:" + str(e) log.exception(errormsg, self.__class__.__name__) data["success"] = False data["error"] = errormsg
def delete(self, name): data = {} db = DBHandler(app.config["DBFILE"]) c = db.getCursor() zone = list( c.execute( """ SELECT name FROM zones WHERE name LIKE ? """, [name])) if len(zone) > 0 and zone[0][0] == name: try: c.execute( """ UPDATE zones SET updated = 1, update_type = 'DELETE' WHERE name LIKE ? """, [name]) db.commit() data["success"] = True data["message"] = u"Entry %s deleted" % (name) except Exception, e: errormsg = u"Unsuccessful database delete transaction:" + str( e) log.exception(errormsg, self.__class__.__name__) data["success"] = False data["error"] = errormsg
def editHost(self, name, host): data = {} db = DBHandler(app.config["DBFILE"]) c = db.getCursor() dbdata = list(c.execute(""" SELECT host FROM zones WHERE name LIKE ? """,[name])) if len(dbdata) == 0: data["error"] = u"Zone doesn't exist" data["success"] = False return data else: zone = dbdata[0] if zone[0] == host: data["error"] = u"Host entry is the same as existing name" data["success"] = False return data try: c.execute(""" UPDATE zones SET host = ?, updated = 1, update_type = 'MODIFIED HOST' WHERE name LIKE ? """,[host,name]) db.commit() data["success"] = True data["message"] = u"Entry %s updated from %s"%(host, zone[0]) except Exception, e: errormsg = u"Unsuccessful database update transaction:" + str(e) log.exception(errormsg, self.__class__.__name__) data["success"] = False data["error"] = errormsg
def editName(self, fromName, toName): data = {} if fromName == toName: data["error"] = u"Name entry is the same as existing name" data["success"] = False return data db = DBHandler(app.config["DBFILE"]) c = db.getCursor() if db.exists("zones", "name", toName): data["error"] = u"Duplicate name entry in db" data["success"] = False return data if not db.exists("zones", "name", fromName): data["error"] = u"No old name entry in db" data["success"] = False return data try: c.execute(""" UPDATE zones SET old_value = name, name = ?, updated = 1, update_type = 'MODIFIED NAME' WHERE name LIKE ? """,[toName, fromName]) db.commit() data["success"] = True data["message"] = u"Entry %s updated from %s"%(toName, fromName) except Exception, e: errormsg = u"Unsuccessful database update transaction:" + str(e) log.exception(errormsg, self.__class__.__name__) data["success"] = False data["error"] = errormsg
def add(self, name, host): data = {} # Check if name exists db = DBHandler(app.config["DBFILE"]) c = db.getCursor() if db.exists("zones", "name", name): data["error"] = u"Duplicate name entry in db" data["success"] = False else: try: c.execute(""" INSERT INTO zones(name,host,updated,update_type) VALUES(?,?,1,'CREATE') """,[name,host]) db.commit() data["success"] = True data["message"] = u"Entry %s inserted"%(name) except Exception, e: errormsg = u"Unsuccessful database insert transaction:" + str(e) log.exception(errormsg, self.__class__.__name__) data["success"] = False data["error"] = errormsg
def delete(self, name): data = {} db = DBHandler(app.config["DBFILE"]) c = db.getCursor() zone = list(c.execute(""" SELECT name FROM zones WHERE name LIKE ? """,[name])) if len(zone) > 0 and zone[0][0] == name: try: c.execute(""" UPDATE zones SET updated = 1, update_type = 'DELETE' WHERE name LIKE ? """,[name]) db.commit() data["success"] = True data["message"] = u"Entry %s deleted"%(name) except Exception, e: errormsg = u"Unsuccessful database delete transaction:" + str(e) log.exception(errormsg, self.__class__.__name__) data["success"] = False data["error"] = errormsg
def add(self, name, host): data = {} # Check if name exists db = DBHandler(app.config["DBFILE"]) c = db.getCursor() if db.exists("zones", "name", name): data["error"] = u"Duplicate name entry in db" data["success"] = False else: try: c.execute( """ INSERT INTO zones(name,host,updated,update_type) VALUES(?,?,1,'CREATE') """, [name, host]) db.commit() data["success"] = True data["message"] = u"Entry %s inserted" % (name) except Exception, e: errormsg = u"Unsuccessful database insert transaction:" + str( e) log.exception(errormsg, self.__class__.__name__) data["success"] = False data["error"] = errormsg
class DNSTest(unittest.TestCase): def setUp(self): self.dh = DNSHandler() self.dfh = DNSFileHandler() self.db = DBHandler(app.config["DBFILE"]) self.c = self.db.getCursor() def tearDown(self): del (self.dh) del (self.dfh) del (self.db) del (self.c) def test_crud_operations(self): # Test add result = self.dh.add("olavtest", "192.168.1.1") assert result["message"] == u"Entry olavtest inserted" assert result["success"] == True # Test duplicate result = self.dh.add("olavtest", "192.168.1.1") assert result["error"] == u"Duplicate name entry in db" assert result["success"] == False # Test edit name # Test duplicate result = self.dh.editName("olavtest", "olavtest") assert result["error"] == u"Name entry is the same as existing name" assert result["success"] == False # Test not found result = self.dh.editName("testtest", "olavtest2") assert result["error"] == u"No old name entry in db" assert result["success"] == False # Test update result = self.dh.editName("olavtest", "olavtest2") assert result["message"] == u"Entry olavtest2 updated from olavtest" assert result["success"] == True # Edit ip # Test duplicate result = self.dh.editHost("olavtest2", "192.168.1.1") assert result["error"] == u"Host entry is the same as existing name" assert result["success"] == False # Test update result = self.dh.editHost("olavtest2", "192.168.1.2") msg = u"Entry 192.168.1.2 updated from 192.168.1.1" assert result["message"] == msg assert result["success"] == True # Test delete # Test not existing name result = self.dh.delete("olavtest") assert result["error"] == u"Entry olavtest not found" assert result["success"] == False # Test delete result = self.dh.delete("olavtest2") assert result["message"] == u"Entry olavtest2 deleted" assert result["success"] == True def test_file_operations(self): shutil.copy2("example.org", app.config["ZONEFILE"]) # Test add self.dh.add("olavfiletest", "192.168.1.1") self.dh.add("olavfiletest2", "test.example.org") results = list( self.c.execute( """ SELECT name, host, update_type, old_value FROM zones WHERE updated = 1 """, [])) self.dfh.updateZonefile(self.dfh.convertResults(results)) lineFound = [False, False] for line in self.dfh.lines: if u"olavfiletest\tIN\tA\t192.168.1.1\n" == line: lineFound[0] = True if u"olavfiletest2\tIN\tCNAME\ttest.example.org.\n" == line: lineFound[1] = True for status in lineFound: assert status is True # Test modify name self.dh.editName("olavfiletest", "olavfiletest3") self.dh.editName("olavfiletest2", "olavfiletest4") results = list( self.c.execute( """ SELECT name, host, update_type, old_value FROM zones WHERE updated = 1 """, [])) self.dfh.updateZonefile(self.dfh.convertResults(results)) lineFound = [False, False] for line in self.dfh.lines: if u"olavfiletest3\tIN\tA\t192.168.1.1\n" == line: lineFound[0] = True if u"olavfiletest4\tIN\tCNAME\ttest.example.org.\n" == line: lineFound[1] = True for status in lineFound: assert status is True # Edit ip self.dh.editHost("olavfiletest3", "test.example.org") self.dh.editHost("olavfiletest4", "192.168.1.2") results = list( self.c.execute( """ SELECT name, host, update_type, old_value FROM zones WHERE updated = 1 """, [])) self.dfh.updateZonefile(self.dfh.convertResults(results)) lineFound = [False, False] for line in self.dfh.lines: if u"olavfiletest3\tIN\tCNAME\ttest.example.org.\n" == line: lineFound[0] = True if u"olavfiletest4\tIN\tA\t192.168.1.2\n" == line: lineFound[1] = True for status in lineFound: assert status is True # Test delete self.dh.delete("olavfiletest4") results = list( self.c.execute( """ SELECT name, host, update_type, old_value FROM zones WHERE updated = 1 """, [])) self.dfh.updateZonefile(self.dfh.convertResults(results)) lineFound = [False] for line in self.dfh.lines: if u"olavfiletest4\tIN\tA\t192.168.1.2\n" == line: lineFound[0] = True for status in lineFound: assert status is False
class DNSFileHandler: def __init__(self): self.zonefile = None self.tempfile = None self.serial = [";Serial", "; Serial"] def __del__(self): if self.zonefile is not None: self.zonefile.close() if self.tempfile is not None: self.tempfile.close() def readZonefile(self): self.zonefile = open(app.config["ZONEFILE"],"r") self.lines = self.zonefile.readlines() return self.lines def createTempFile(self): self.tempfile = open(app.config["TEMPZONEFILE"],"w") def moveZoneFile(self): os.rename(app.config["TEMPZONEFILE"], app.config["ZONEFILE"] ) def getAllEntries(self, lines): # return all entries found in the zone file data = [] printLines = False for line in lines: if line.find(app.config["ZONES_END_POINT"]) >= 0: printLines = False if printLines: zsplit = line.split() if len(zsplit) == 4: data.append(ZoneEntry(zsplit[0],zsplit[3])) if line.find(app.config["ZONES_START_POINT"]) >= 0: printLines = True return data def reloadBind(self): if call(app.config["BIND_RELOAD_CMD"], shell=True) != 0: errormsg = u"Couldn't reload BIND." log.exception(errormsg, self.__class__.__name__) def zonefileJob(self): self.db = DBHandler(app.config["DBFILE"]) self.c = self.db.getCursor() results = list(self.c.execute(""" SELECT name, host, update_type, old_value FROM zones WHERE updated = 1 """,[])) if len(results) > 0: self.updateZonefile(self.convertResults(results)) def updateZonefile(self, zones): self.readZonefile() self.createTempFile() for zone in zones: self.templines = [] if zone.updateType == "CREATE": self.addZone(zone) elif "MODIFIED" in zone.updateType: self.updateZone(zone) elif zone.updateType == "DELETE": self.deleteZone(zone) app.logger.info(zone.updateType+" zone: "+str(zone.name)) for item in ["CREATE", "MODIFIED", "DELETE"]: if item in zone.updateType: self.lines = list(self.templines) self.updateSerial() for line in self.lines: self.tempfile.write(line) self.tempfile.close() self.moveZoneFile() self.reloadBind() def addZone(self, zone): added = False for i, line in enumerate(self.lines): if app.config["ZONES_END_POINT"] in line: # Check if ip address or hostname try: socket.inet_aton(zone.host) newline = "%s\tIN\tA\t%s\n"%(zone.name,zone.host) except: if not zone.host[:-1] == ".": zone.host = zone.host + "." newline = "%s\tIN\tCNAME\t%s\n"%( zone.name,zone.host) self.templines.insert(i, newline) added = True if added: self.templines.insert(i+1, line) else: self.templines.insert(i, line) if added: try: self.c.execute(""" UPDATE zones SET updated = 0, update_type = NULL WHERE name LIKE ? """,[zone.name]) self.db.commit() except Exception, e: errormsg = u"Unsuccessful database update transaction:" + str(e) log.exception(errormsg, self.__class__.__name__)
class DNSTest(unittest.TestCase): def setUp(self): self.dh = DNSHandler() self.dfh = DNSFileHandler() self.db = DBHandler(app.config["DBFILE"]) self.c = self.db.getCursor() def tearDown(self): del(self.dh) del(self.dfh) del(self.db) del(self.c) def test_crud_operations(self): # Test add result = self.dh.add("olavtest", "192.168.1.1") assert result["message"] == u"Entry olavtest inserted" assert result["success"] == True # Test duplicate result = self.dh.add("olavtest", "192.168.1.1") assert result["error"] == u"Duplicate name entry in db" assert result["success"] == False # Test edit name # Test duplicate result = self.dh.editName("olavtest", "olavtest") assert result["error"] == u"Name entry is the same as existing name" assert result["success"] == False # Test not found result = self.dh.editName("testtest", "olavtest2") assert result["error"] == u"No old name entry in db" assert result["success"] == False # Test update result = self.dh.editName("olavtest", "olavtest2") assert result["message"] == u"Entry olavtest2 updated from olavtest" assert result["success"] == True # Edit ip # Test duplicate result = self.dh.editHost("olavtest2", "192.168.1.1") assert result["error"] == u"Host entry is the same as existing name" assert result["success"] == False # Test update result = self.dh.editHost("olavtest2", "192.168.1.2") msg = u"Entry 192.168.1.2 updated from 192.168.1.1" assert result["message"] == msg assert result["success"] == True # Test delete # Test not existing name result = self.dh.delete("olavtest") assert result["error"] == u"Entry olavtest not found" assert result["success"] == False # Test delete result = self.dh.delete("olavtest2") assert result["message"] == u"Entry olavtest2 deleted" assert result["success"] == True def test_file_operations(self): shutil.copy2( "example.org", app.config["ZONEFILE"] ) # Test add self.dh.add("olavfiletest", "192.168.1.1") self.dh.add("olavfiletest2", "test.example.org") results = list(self.c.execute(""" SELECT name, host, update_type, old_value FROM zones WHERE updated = 1 """,[])) self.dfh.updateZonefile(self.dfh.convertResults(results)) lineFound = [False,False] for line in self.dfh.lines: if u"olavfiletest\tIN\tA\t192.168.1.1\n" == line: lineFound[0] = True if u"olavfiletest2\tIN\tCNAME\ttest.example.org.\n" == line: lineFound[1] = True for status in lineFound: assert status is True # Test modify name self.dh.editName("olavfiletest", "olavfiletest3") self.dh.editName("olavfiletest2", "olavfiletest4") results = list(self.c.execute(""" SELECT name, host, update_type, old_value FROM zones WHERE updated = 1 """,[])) self.dfh.updateZonefile(self.dfh.convertResults(results)) lineFound = [False,False] for line in self.dfh.lines: if u"olavfiletest3\tIN\tA\t192.168.1.1\n" == line: lineFound[0] = True if u"olavfiletest4\tIN\tCNAME\ttest.example.org.\n" == line: lineFound[1] = True for status in lineFound: assert status is True # Edit ip self.dh.editHost("olavfiletest3", "test.example.org") self.dh.editHost("olavfiletest4", "192.168.1.2") results = list(self.c.execute(""" SELECT name, host, update_type, old_value FROM zones WHERE updated = 1 """,[])) self.dfh.updateZonefile(self.dfh.convertResults(results)) lineFound = [False,False] for line in self.dfh.lines: if u"olavfiletest3\tIN\tCNAME\ttest.example.org.\n" == line: lineFound[0] = True if u"olavfiletest4\tIN\tA\t192.168.1.2\n" == line: lineFound[1] = True for status in lineFound: assert status is True # Test delete self.dh.delete("olavfiletest4") results = list(self.c.execute(""" SELECT name, host, update_type, old_value FROM zones WHERE updated = 1 """,[])) self.dfh.updateZonefile(self.dfh.convertResults(results)) lineFound = [False] for line in self.dfh.lines: if u"olavfiletest4\tIN\tA\t192.168.1.2\n" == line: lineFound[0] = True for status in lineFound: assert status is False