mirror of https://github.com/fail2ban/fail2ban
ENH: Add cache for database getBansMerged
This is avoids duplicate queries when using the ip(jail)matches and ip(jail)failures in actionspull/491/head
parent
40007abc1d
commit
fb7511fdea
|
@ -64,6 +64,8 @@ class Fail2BanDb(object):
|
||||||
self._dbFilename = filename
|
self._dbFilename = filename
|
||||||
self._purgeAge = purgeAge
|
self._purgeAge = purgeAge
|
||||||
|
|
||||||
|
self._bansMergedCache = {}
|
||||||
|
|
||||||
logSys.info(
|
logSys.info(
|
||||||
"Connected to fail2ban persistent database '%s'", filename)
|
"Connected to fail2ban persistent database '%s'", filename)
|
||||||
except sqlite3.OperationalError, e:
|
except sqlite3.OperationalError, e:
|
||||||
|
@ -219,6 +221,7 @@ class Fail2BanDb(object):
|
||||||
|
|
||||||
@commitandrollback
|
@commitandrollback
|
||||||
def addBan(self, cur, jail, ticket):
|
def addBan(self, cur, jail, ticket):
|
||||||
|
self._bansMergedCache = {}
|
||||||
#TODO: Implement data parts once arbitrary match keys completed
|
#TODO: Implement data parts once arbitrary match keys completed
|
||||||
cur.execute(
|
cur.execute(
|
||||||
"INSERT INTO bans(jail, ip, timeofban, data) VALUES(?, ?, ?, ?)",
|
"INSERT INTO bans(jail, ip, timeofban, data) VALUES(?, ?, ?, ?)",
|
||||||
|
@ -253,6 +256,9 @@ class Fail2BanDb(object):
|
||||||
return tickets
|
return tickets
|
||||||
|
|
||||||
def getBansMerged(self, ip, jail=None, **kwargs):
|
def getBansMerged(self, ip, jail=None, **kwargs):
|
||||||
|
cacheKey = ip if jail is None else "%s|%s" % (ip, jail.getName())
|
||||||
|
if cacheKey in self._bansMergedCache:
|
||||||
|
return self._bansMergedCache[cacheKey]
|
||||||
matches = []
|
matches = []
|
||||||
failures = 0
|
failures = 0
|
||||||
for ip, timeofban, data in self._getBans(ip=ip, jail=jail, **kwargs):
|
for ip, timeofban, data in self._getBans(ip=ip, jail=jail, **kwargs):
|
||||||
|
@ -261,10 +267,12 @@ class Fail2BanDb(object):
|
||||||
failures += data['failures']
|
failures += data['failures']
|
||||||
ticket = FailTicket(ip, timeofban, matches)
|
ticket = FailTicket(ip, timeofban, matches)
|
||||||
ticket.setAttempt(failures)
|
ticket.setAttempt(failures)
|
||||||
|
self._bansMergedCache[cacheKey] = ticket
|
||||||
return ticket
|
return ticket
|
||||||
|
|
||||||
@commitandrollback
|
@commitandrollback
|
||||||
def purge(self, cur):
|
def purge(self, cur):
|
||||||
|
self._bansMergedCache = {}
|
||||||
cur.execute(
|
cur.execute(
|
||||||
"DELETE FROM bans WHERE timeofban < ?",
|
"DELETE FROM bans WHERE timeofban < ?",
|
||||||
(MyTime.time() - self._purgeAge, ))
|
(MyTime.time() - self._purgeAge, ))
|
||||||
|
|
|
@ -162,6 +162,20 @@ class DatabaseTest(unittest.TestCase):
|
||||||
self.assertEqual(ticket.getAttempt(), 30)
|
self.assertEqual(ticket.getAttempt(), 30)
|
||||||
self.assertEqual(ticket.getMatches(), ["abc\n", "123\n"])
|
self.assertEqual(ticket.getMatches(), ["abc\n", "123\n"])
|
||||||
|
|
||||||
|
# Should cache result if no extra bans added
|
||||||
|
ticketID = id(ticket)
|
||||||
|
self.assertEqual(
|
||||||
|
ticketID,
|
||||||
|
id(self.db.getBansMerged("127.0.0.1", jail=self.jail)))
|
||||||
|
|
||||||
|
ticket = FailTicket("127.0.0.1", 40, ["ABC\n"])
|
||||||
|
ticket.setAttempt(40)
|
||||||
|
self.db.addBan(jail2, ticket)
|
||||||
|
# Added ticket, so cache should have been cleared
|
||||||
|
self.assertNotEqual(
|
||||||
|
ticketID,
|
||||||
|
id(self.db.getBansMerged("127.0.0.1", jail=self.jail)))
|
||||||
|
|
||||||
def testPurge(self):
|
def testPurge(self):
|
||||||
self.testAddJail() # Add jail
|
self.testAddJail() # Add jail
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue