mirror of https://github.com/fail2ban/fail2ban
ConfigReader/ConfigWrapper renamed as suggested from @yarikoptic;
+ code clarifying (suggested also);pull/824/head
parent
f6723a12ff
commit
f67053c2ec
|
@ -92,7 +92,7 @@ class SafeConfigParserWithIncludes(object):
|
||||||
return orig_attr
|
return orig_attr
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _resource_mtime(resource):
|
def _get_resource_fingerprint(resource):
|
||||||
mt = []
|
mt = []
|
||||||
dirnames = []
|
dirnames = []
|
||||||
for filename in resource:
|
for filename in resource:
|
||||||
|
@ -126,7 +126,7 @@ class SafeConfigParserWithIncludes(object):
|
||||||
# check cache
|
# check cache
|
||||||
hashv = '\x01'.join(fileNamesFull)
|
hashv = '\x01'.join(fileNamesFull)
|
||||||
cr, ret, mtime = SCPWI.CFG_CACHE.get(hashv, (None, False, 0))
|
cr, ret, mtime = SCPWI.CFG_CACHE.get(hashv, (None, False, 0))
|
||||||
curmt = SCPWI._resource_mtime(fileNamesFull)
|
curmt = SCPWI._get_resource_fingerprint(fileNamesFull)
|
||||||
if cr is not None and mtime == curmt:
|
if cr is not None and mtime == curmt:
|
||||||
self.__cr = cr
|
self.__cr = cr
|
||||||
logSys.debug("Cached config files: %s", resource)
|
logSys.debug("Cached config files: %s", resource)
|
||||||
|
@ -160,7 +160,7 @@ class SafeConfigParserWithIncludes(object):
|
||||||
# check cache
|
# check cache
|
||||||
hashv = '///'.join(resources)
|
hashv = '///'.join(resources)
|
||||||
cinc, mtime = SCPWI.CFG_INC_CACHE.get(hashv, (None, 0))
|
cinc, mtime = SCPWI.CFG_INC_CACHE.get(hashv, (None, 0))
|
||||||
curmt = SCPWI._resource_mtime(resources)
|
curmt = SCPWI._get_resource_fingerprint(resources)
|
||||||
if cinc is not None and mtime == curmt:
|
if cinc is not None and mtime == curmt:
|
||||||
return cinc
|
return cinc
|
||||||
|
|
||||||
|
|
|
@ -32,9 +32,13 @@ from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
logLevel = 6
|
_logLevel = 6
|
||||||
|
|
||||||
class ConfigWrapper():
|
class ConfigReader():
|
||||||
|
"""Config reader class (previously ConfigWrapper).
|
||||||
|
|
||||||
|
Automatically shares or use already shared instance of ConfigReaderUnshared.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, use_config=None, share_config=None, **kwargs):
|
def __init__(self, use_config=None, share_config=None, **kwargs):
|
||||||
# use given shared config if possible (see read):
|
# use given shared config if possible (see read):
|
||||||
|
@ -48,7 +52,7 @@ class ConfigWrapper():
|
||||||
self._cfg_share = share_config
|
self._cfg_share = share_config
|
||||||
self._cfg_share_kwargs = kwargs
|
self._cfg_share_kwargs = kwargs
|
||||||
else:
|
else:
|
||||||
self._cfg = ConfigReader(**kwargs)
|
self._cfg = ConfigReaderUnshared(**kwargs)
|
||||||
|
|
||||||
def setBaseDir(self, basedir):
|
def setBaseDir(self, basedir):
|
||||||
self._cfg.setBaseDir(basedir)
|
self._cfg.setBaseDir(basedir)
|
||||||
|
@ -61,7 +65,7 @@ class ConfigWrapper():
|
||||||
if not self._cfg and self._cfg_share is not None:
|
if not self._cfg and self._cfg_share is not None:
|
||||||
self._cfg = self._cfg_share.get(name)
|
self._cfg = self._cfg_share.get(name)
|
||||||
if not self._cfg:
|
if not self._cfg:
|
||||||
self._cfg = ConfigReader(**self._cfg_share_kwargs)
|
self._cfg = ConfigReaderUnshared(**self._cfg_share_kwargs)
|
||||||
self._cfg_share[name] = self._cfg
|
self._cfg_share[name] = self._cfg
|
||||||
# performance feature - read once if using shared config reader:
|
# performance feature - read once if using shared config reader:
|
||||||
rc = self._cfg.read_cfg_files
|
rc = self._cfg.read_cfg_files
|
||||||
|
@ -92,7 +96,12 @@ class ConfigWrapper():
|
||||||
return self._cfg.getOptions(*args, **kwargs)
|
return self._cfg.getOptions(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class ConfigReader(SafeConfigParserWithIncludes):
|
class ConfigReaderUnshared(SafeConfigParserWithIncludes):
|
||||||
|
"""Unshared config reader (previously ConfigReader).
|
||||||
|
|
||||||
|
Does not use this class (internal not shared/cached represenation).
|
||||||
|
Use ConfigReader instead.
|
||||||
|
"""
|
||||||
|
|
||||||
DEFAULT_BASEDIR = '/etc/fail2ban'
|
DEFAULT_BASEDIR = '/etc/fail2ban'
|
||||||
|
|
||||||
|
@ -103,7 +112,7 @@ class ConfigReader(SafeConfigParserWithIncludes):
|
||||||
|
|
||||||
def setBaseDir(self, basedir):
|
def setBaseDir(self, basedir):
|
||||||
if basedir is None:
|
if basedir is None:
|
||||||
basedir = ConfigReader.DEFAULT_BASEDIR # stock system location
|
basedir = ConfigReaderUnshared.DEFAULT_BASEDIR # stock system location
|
||||||
self._basedir = basedir.rstrip('/')
|
self._basedir = basedir.rstrip('/')
|
||||||
|
|
||||||
def getBaseDir(self):
|
def getBaseDir(self):
|
||||||
|
@ -181,15 +190,15 @@ class ConfigReader(SafeConfigParserWithIncludes):
|
||||||
logSys.warning("'%s' not defined in '%s'. Using default one: %r"
|
logSys.warning("'%s' not defined in '%s'. Using default one: %r"
|
||||||
% (option[1], sec, option[2]))
|
% (option[1], sec, option[2]))
|
||||||
values[option[1]] = option[2]
|
values[option[1]] = option[2]
|
||||||
elif logSys.getEffectiveLevel() <= logLevel:
|
elif logSys.getEffectiveLevel() <= _logLevel:
|
||||||
logSys.log(logLevel, "Non essential option '%s' not defined in '%s'.", option[1], sec)
|
logSys.log(_logLevel, "Non essential option '%s' not defined in '%s'.", option[1], sec)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
logSys.warning("Wrong value for '" + option[1] + "' in '" + sec +
|
logSys.warning("Wrong value for '" + option[1] + "' in '" + sec +
|
||||||
"'. Using default one: '" + `option[2]` + "'")
|
"'. Using default one: '" + `option[2]` + "'")
|
||||||
values[option[1]] = option[2]
|
values[option[1]] = option[2]
|
||||||
return values
|
return values
|
||||||
|
|
||||||
class DefinitionInitConfigReader(ConfigWrapper):
|
class DefinitionInitConfigReader(ConfigReader):
|
||||||
"""Config reader for files with options grouped in [Definition] and
|
"""Config reader for files with options grouped in [Definition] and
|
||||||
[Init] sections.
|
[Init] sections.
|
||||||
|
|
||||||
|
@ -201,7 +210,7 @@ class DefinitionInitConfigReader(ConfigWrapper):
|
||||||
_configOpts = []
|
_configOpts = []
|
||||||
|
|
||||||
def __init__(self, file_, jailName, initOpts, **kwargs):
|
def __init__(self, file_, jailName, initOpts, **kwargs):
|
||||||
ConfigWrapper.__init__(self, **kwargs)
|
ConfigReader.__init__(self, **kwargs)
|
||||||
self.setFile(file_)
|
self.setFile(file_)
|
||||||
self.setJailName(jailName)
|
self.setJailName(jailName)
|
||||||
self._initOpts = initOpts
|
self._initOpts = initOpts
|
||||||
|
@ -220,14 +229,14 @@ class DefinitionInitConfigReader(ConfigWrapper):
|
||||||
return self._jailName
|
return self._jailName
|
||||||
|
|
||||||
def read(self):
|
def read(self):
|
||||||
return ConfigWrapper.read(self, self._file)
|
return ConfigReader.read(self, self._file)
|
||||||
|
|
||||||
# needed for fail2ban-regex that doesn't need fancy directories
|
# needed for fail2ban-regex that doesn't need fancy directories
|
||||||
def readexplicit(self):
|
def readexplicit(self):
|
||||||
return SafeConfigParserWithIncludes.read(self, self._file)
|
return SafeConfigParserWithIncludes.read(self, self._file)
|
||||||
|
|
||||||
def getOptions(self, pOpts):
|
def getOptions(self, pOpts):
|
||||||
self._opts = ConfigWrapper.getOptions(
|
self._opts = ConfigReader.getOptions(
|
||||||
self, "Definition", self._configOpts, pOpts)
|
self, "Definition", self._configOpts, pOpts)
|
||||||
|
|
||||||
if self.has_section("Init"):
|
if self.has_section("Init"):
|
||||||
|
|
|
@ -24,32 +24,32 @@ __author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
from .configreader import ConfigWrapper
|
from .configreader import ConfigReader
|
||||||
from ..helpers import getLogger
|
from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
class Fail2banReader(ConfigWrapper):
|
class Fail2banReader(ConfigReader):
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
self.__opts = None
|
self.__opts = None
|
||||||
ConfigWrapper.__init__(self, **kwargs)
|
ConfigReader.__init__(self, **kwargs)
|
||||||
|
|
||||||
def read(self):
|
def read(self):
|
||||||
ConfigWrapper.read(self, "fail2ban")
|
ConfigReader.read(self, "fail2ban")
|
||||||
|
|
||||||
def getEarlyOptions(self):
|
def getEarlyOptions(self):
|
||||||
opts = [["string", "socket", "/var/run/fail2ban/fail2ban.sock"],
|
opts = [["string", "socket", "/var/run/fail2ban/fail2ban.sock"],
|
||||||
["string", "pidfile", "/var/run/fail2ban/fail2ban.pid"]]
|
["string", "pidfile", "/var/run/fail2ban/fail2ban.pid"]]
|
||||||
return ConfigWrapper.getOptions(self, "Definition", opts)
|
return ConfigReader.getOptions(self, "Definition", opts)
|
||||||
|
|
||||||
def getOptions(self):
|
def getOptions(self):
|
||||||
opts = [["string", "loglevel", "INFO" ],
|
opts = [["string", "loglevel", "INFO" ],
|
||||||
["string", "logtarget", "STDERR"],
|
["string", "logtarget", "STDERR"],
|
||||||
["string", "dbfile", "/var/lib/fail2ban/fail2ban.sqlite3"],
|
["string", "dbfile", "/var/lib/fail2ban/fail2ban.sqlite3"],
|
||||||
["int", "dbpurgeage", 86400]]
|
["int", "dbpurgeage", 86400]]
|
||||||
self.__opts = ConfigWrapper.getOptions(self, "Definition", opts)
|
self.__opts = ConfigReader.getOptions(self, "Definition", opts)
|
||||||
|
|
||||||
def convert(self):
|
def convert(self):
|
||||||
stream = list()
|
stream = list()
|
||||||
|
|
|
@ -27,7 +27,7 @@ __license__ = "GPL"
|
||||||
import re, glob, os.path
|
import re, glob, os.path
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from .configreader import ConfigReader, ConfigWrapper
|
from .configreader import ConfigReaderUnshared, ConfigReader
|
||||||
from .filterreader import FilterReader
|
from .filterreader import FilterReader
|
||||||
from .actionreader import ActionReader
|
from .actionreader import ActionReader
|
||||||
from ..helpers import getLogger
|
from ..helpers import getLogger
|
||||||
|
@ -35,7 +35,7 @@ from ..helpers import getLogger
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
class JailReader(ConfigWrapper):
|
class JailReader(ConfigReader):
|
||||||
|
|
||||||
optionCRE = re.compile("^((?:\w|-|_|\.)+)(?:\[(.*)\])?$")
|
optionCRE = re.compile("^((?:\w|-|_|\.)+)(?:\[(.*)\])?$")
|
||||||
optionExtractRE = re.compile(
|
optionExtractRE = re.compile(
|
||||||
|
@ -43,7 +43,7 @@ class JailReader(ConfigWrapper):
|
||||||
|
|
||||||
def __init__(self, name, force_enable=False, cfg_share=None, **kwargs):
|
def __init__(self, name, force_enable=False, cfg_share=None, **kwargs):
|
||||||
# use shared config if possible:
|
# use shared config if possible:
|
||||||
ConfigWrapper.__init__(self, **kwargs)
|
ConfigReader.__init__(self, **kwargs)
|
||||||
self.__name = name
|
self.__name = name
|
||||||
self.__filter = None
|
self.__filter = None
|
||||||
self.__force_enable = force_enable
|
self.__force_enable = force_enable
|
||||||
|
@ -62,7 +62,7 @@ class JailReader(ConfigWrapper):
|
||||||
return self.__name
|
return self.__name
|
||||||
|
|
||||||
def read(self):
|
def read(self):
|
||||||
out = ConfigWrapper.read(self, "jail")
|
out = ConfigReader.read(self, "jail")
|
||||||
# Before returning -- verify that requested section
|
# Before returning -- verify that requested section
|
||||||
# exists at all
|
# exists at all
|
||||||
if not (self.__name in self.sections()):
|
if not (self.__name in self.sections()):
|
||||||
|
@ -103,7 +103,7 @@ class JailReader(ConfigWrapper):
|
||||||
["string", "ignoreip", None],
|
["string", "ignoreip", None],
|
||||||
["string", "filter", ""],
|
["string", "filter", ""],
|
||||||
["string", "action", ""]]
|
["string", "action", ""]]
|
||||||
self.__opts = ConfigWrapper.getOptions(self, self.__name, opts)
|
self.__opts = ConfigReader.getOptions(self, self.__name, opts)
|
||||||
if not self.__opts:
|
if not self.__opts:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ class JailReader(ConfigWrapper):
|
||||||
if self.__filter:
|
if self.__filter:
|
||||||
stream.extend(self.__filter.convert())
|
stream.extend(self.__filter.convert())
|
||||||
for action in self.__actions:
|
for action in self.__actions:
|
||||||
if isinstance(action, (ConfigReader, ConfigWrapper)):
|
if isinstance(action, (ConfigReaderUnshared, ConfigReader)):
|
||||||
stream.extend(action.convert())
|
stream.extend(action.convert())
|
||||||
else:
|
else:
|
||||||
stream.append(action)
|
stream.append(action)
|
||||||
|
|
|
@ -24,14 +24,14 @@ __author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
from .configreader import ConfigReader, ConfigWrapper
|
from .configreader import ConfigReader
|
||||||
from .jailreader import JailReader
|
from .jailreader import JailReader
|
||||||
from ..helpers import getLogger
|
from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
class JailsReader(ConfigWrapper):
|
class JailsReader(ConfigReader):
|
||||||
|
|
||||||
def __init__(self, force_enable=False, **kwargs):
|
def __init__(self, force_enable=False, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
@ -42,7 +42,7 @@ class JailsReader(ConfigWrapper):
|
||||||
It is for internal use
|
It is for internal use
|
||||||
"""
|
"""
|
||||||
# use shared config if possible:
|
# use shared config if possible:
|
||||||
ConfigWrapper.__init__(self, **kwargs)
|
ConfigReader.__init__(self, **kwargs)
|
||||||
self.__cfg_share = dict()
|
self.__cfg_share = dict()
|
||||||
self.__jails = list()
|
self.__jails = list()
|
||||||
self.__force_enable = force_enable
|
self.__force_enable = force_enable
|
||||||
|
@ -52,13 +52,13 @@ class JailsReader(ConfigWrapper):
|
||||||
return self.__jails
|
return self.__jails
|
||||||
|
|
||||||
def read(self):
|
def read(self):
|
||||||
return ConfigWrapper.read(self, "jail")
|
return ConfigReader.read(self, "jail")
|
||||||
|
|
||||||
def getOptions(self, section=None):
|
def getOptions(self, section=None):
|
||||||
"""Reads configuration for jail(s) and adds enabled jails to __jails
|
"""Reads configuration for jail(s) and adds enabled jails to __jails
|
||||||
"""
|
"""
|
||||||
opts = []
|
opts = []
|
||||||
self.__opts = ConfigWrapper.getOptions(self, "Definition", opts)
|
self.__opts = ConfigReader.getOptions(self, "Definition", opts)
|
||||||
|
|
||||||
if section is None:
|
if section is None:
|
||||||
sections = self.sections()
|
sections = self.sections()
|
||||||
|
|
|
@ -21,9 +21,9 @@ __author__ = "Cyril Jaquier, Yaroslav Halchenko"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2013 Yaroslav Halchenko"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2013 Yaroslav Halchenko"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import os, glob, shutil, tempfile, unittest, time, re
|
import os, glob, shutil, tempfile, unittest, re
|
||||||
|
|
||||||
from ..client.configreader import ConfigReader
|
from ..client.configreader import ConfigReaderUnshared
|
||||||
from ..client.jailreader import JailReader
|
from ..client.jailreader import JailReader
|
||||||
from ..client.filterreader import FilterReader
|
from ..client.filterreader import FilterReader
|
||||||
from ..client.jailsreader import JailsReader
|
from ..client.jailsreader import JailsReader
|
||||||
|
@ -46,7 +46,7 @@ class ConfigReaderTest(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
"""Call before every test case."""
|
"""Call before every test case."""
|
||||||
self.d = tempfile.mkdtemp(prefix="f2b-temp")
|
self.d = tempfile.mkdtemp(prefix="f2b-temp")
|
||||||
self.c = ConfigReader(basedir=self.d)
|
self.c = ConfigReaderUnshared(basedir=self.d)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
"""Call after every test case."""
|
"""Call after every test case."""
|
||||||
|
|
Loading…
Reference in New Issue