Update extended status to accept additional argument, flavor

Default to as-in behavior, or flavor=="basic"
pull/924/head
Lee Clemens 2015-01-26 19:38:06 -05:00
parent dfe4d02f65
commit 486214585e
9 changed files with 71 additions and 62 deletions

View File

@ -41,9 +41,10 @@ ver. 0.9.2 (2014/XX/XXX) - wanna-be-released
- Monit config for fail2ban in /files/monit - Monit config for fail2ban in /files/monit
- New actions: - New actions:
- action.d/firewallcmd-multiport and action.d/firewallcmd-allports Thanks Donald Yandt - action.d/firewallcmd-multiport and action.d/firewallcmd-allports Thanks Donald Yandt
- New status commands: - New status argument, flavor:
- fail2ban-client status <jail> extended - fail2ban-client status <jail> [flavor]
- prints Cymru data (ASN, Country RIR) per banned IP - empty or "basic" works as-is
- "cymru" additionally prints (ASN, Country RIR) per banned IP
- Requires dnspython or dnspython3 - Requires dnspython or dnspython3
- Enhancements: - Enhancements:

View File

@ -370,22 +370,21 @@ class Actions(JailThread, Mapping):
self._jail.name, name, aInfo, e, self._jail.name, name, aInfo, e,
exc_info=logSys.getEffectiveLevel()<=logging.DEBUG) exc_info=logSys.getEffectiveLevel()<=logging.DEBUG)
@property def status(self, flavor="basic"):
def status(self):
"""Status of current and total ban counts and current banned IP list. """Status of current and total ban counts and current banned IP list.
""" """
ret = [("Currently banned", self.__banManager.size()), # TODO: Allow this list to be printed as 'status' output
supported_flavors = ["basic", "cymru"]
if flavor is None or flavor not in supported_flavors:
logSys.warning("Unsupported extended jail status flavor %r. Supported: %s" % (flavor, supported_flavors))
# Always print this information (basic)
ret = [("Currently banned", self.__banManager.size()),
("Total banned", self.__banManager.getBanTotal()), ("Total banned", self.__banManager.getBanTotal()),
("Banned IP list", self.__banManager.getBanList())] ("Banned IP list", self.__banManager.getBanList())]
return ret if flavor == "cymru":
cymru_info = self.__banManager.getBanListExtendedCymruInfo()
@property ret += \
def statusExtended(self): [("Banned ASN list", self.__banManager.geBanListExtendedASN(cymru_info)),
"""Jail status plus banned IPs' ASN, Country and RIR ("Banned Country list", self.__banManager.geBanListExtendedCountry(cymru_info)),
""" ("Banned RIR list", self.__banManager.geBanListExtendedRIR(cymru_info))]
cymru_info = self.__banManager.getBanListExtendedCymruInfo()
ret = self.status +\
[("Banned ASN list", self.__banManager.geBanListExtendedASN(cymru_info)),
("Banned Country list", self.__banManager.geBanListExtendedCountry(cymru_info)),
("Banned RIR list", self.__banManager.geBanListExtendedRIR(cymru_info))]
return ret return ret

View File

@ -529,8 +529,7 @@ class Filter(JailThread):
logSys.error(e) logSys.error(e)
return failList return failList
@property def status(self, flavor="basic"):
def status(self):
"""Status of failures detected by filter. """Status of failures detected by filter.
""" """
ret = [("Currently failed", self.failManager.size()), ret = [("Currently failed", self.failManager.size()),
@ -686,11 +685,10 @@ class FileFilter(Filter):
db.updateLog(self.jail, container) db.updateLog(self.jail, container)
return True return True
@property def status(self, flavor="basic"):
def status(self):
"""Status of Filter plus files being monitored. """Status of Filter plus files being monitored.
""" """
ret = super(FileFilter, self).status ret = super(FileFilter, self).status(flavor=flavor)
path = [m.getFileName() for m in self.getLogPath()] path = [m.getFileName() for m in self.getLogPath()]
ret.append(("File list", path)) ret.append(("File list", path))
return ret return ret

View File

@ -259,9 +259,8 @@ class FilterSystemd(JournalFilter): # pragma: systemd no cover
or "jailless") +" filter terminated") or "jailless") +" filter terminated")
return True return True
@property def status(self, flavor="basic"):
def status(self): ret = super(FilterSystemd, self).status(flavor=flavor)
ret = super(FilterSystemd, self).status
ret.append(("Journal matches", ret.append(("Journal matches",
[" + ".join(" ".join(match) for match in self.__matches)])) [" + ".join(" ".join(match) for match in self.__matches)]))
return ret return ret

View File

@ -174,22 +174,12 @@ class Jail:
self.filter.idle = value self.filter.idle = value
self.actions.idle = value self.actions.idle = value
@property def status(self, flavor="basic"):
def status(self):
"""The status of the jail. """The status of the jail.
""" """
return [ return [
("Filter", self.filter.status), ("Filter", self.filter.status(flavor=flavor)),
("Actions", self.actions.status), ("Actions", self.actions.status(flavor=flavor)),
]
@property
def statusExtended(self):
"""The extended status of the jail.
"""
return [
("Filter", self.filter.status),
("Actions", self.actions.statusExtended),
] ]
def putFailTicket(self, ticket): def putFailTicket(self, ticket):

View File

@ -26,7 +26,7 @@ __license__ = "GPL"
import sys import sys
from threading import Thread from threading import Thread
from abc import abstractproperty, abstractmethod from abc import abstractmethod
from ..helpers import excepthook from ..helpers import excepthook
@ -66,18 +66,12 @@ class JailThread(Thread):
excepthook(*sys.exc_info()) excepthook(*sys.exc_info())
self.run = run_with_except_hook self.run = run_with_except_hook
@abstractproperty @abstractmethod
def status(self): # pragma: no cover - abstract def status(self, flavor="basic"): # pragma: no cover - abstract
"""Abstract - Should provide status information. """Abstract - Should provide status information.
""" """
pass pass
@abstractproperty
def statusExtended(self): # pragma: no cover - abstract
"""Abstract - Should provide extended status information.
"""
pass
def start(self): def start(self):
"""Sets active flag and starts thread. """Sets active flag and starts thread.
""" """

View File

@ -320,11 +320,8 @@ class Server:
finally: finally:
self.__lock.release() self.__lock.release()
def statusJail(self, name): def statusJail(self, name, flavor="basic"):
return self.__jails[name].status return self.__jails[name].status(flavor=flavor)
def statusJailExtended(self, name):
return self.__jails[name].statusExtended
# Logging # Logging

View File

@ -335,8 +335,6 @@ class Transmitter:
return self.__server.statusJail(name) return self.__server.statusJail(name)
elif len(command) == 2: elif len(command) == 2:
name = command[0] name = command[0]
if command[1] == "extended": flavor = command[1]
return self.__server.statusJailExtended(name) return self.__server.statusJail(name, flavor=flavor)
else:
raise Exception("Invalid command (invalid status extension)")
raise Exception("Invalid command (no status)") raise Exception("Invalid command (no status)")

View File

@ -474,8 +474,44 @@ class Transmitter(TransmitterBase):
) )
) )
def testJailStatusExtended(self): def testJailStatusBasic(self):
self.assertEqual(self.transm.proceed(["status", self.jailName, "extended"]), self.assertEqual(self.transm.proceed(["status", self.jailName, "basic"]),
(0,
[
('Filter', [
('Currently failed', 0),
('Total failed', 0),
('File list', [])]
),
('Actions', [
('Currently banned', 0),
('Total banned', 0),
('Banned IP list', [])]
)
]
)
)
def testJailStatusBasicKwarg(self):
self.assertEqual(self.transm.proceed(["status", self.jailName, "INVALID"]),
(0,
[
('Filter', [
('Currently failed', 0),
('Total failed', 0),
('File list', [])]
),
('Actions', [
('Currently banned', 0),
('Total banned', 0),
('Banned IP list', [])]
)
]
)
)
def testJailStatusCymru(self):
self.assertEqual(self.transm.proceed(["status", self.jailName, "cymru"]),
(0, (0,
[ [
('Filter', [ ('Filter', [
@ -495,6 +531,7 @@ class Transmitter(TransmitterBase):
) )
) )
def testAction(self): def testAction(self):
action = "TestCaseAction" action = "TestCaseAction"
cmdList = [ cmdList = [
@ -622,10 +659,6 @@ class Transmitter(TransmitterBase):
self.assertEqual( self.assertEqual(
self.transm.proceed(["status", "INVALID", "COMMAND"])[0],1) self.transm.proceed(["status", "INVALID", "COMMAND"])[0],1)
def testStatusJailExtendedNOK(self):
self.assertEqual(
self.transm.proceed(["status", self.jailName, "INVALID_COMMAND"])[0],1)
def testJournalMatch(self): def testJournalMatch(self):
if not filtersystemd: # pragma: no cover if not filtersystemd: # pragma: no cover
if sys.version_info >= (2, 7): if sys.version_info >= (2, 7):