ConfigReader/ConfigWrapper renamed as suggested from @yarikoptic;

+ code clarifying (suggested also);
pull/824/head
sebres 2014-10-09 19:01:49 +02:00
parent f6723a12ff
commit f67053c2ec
6 changed files with 44 additions and 35 deletions

View File

@ -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

View File

@ -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"):

View File

@ -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()

View File

@ -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)

View File

@ -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()

View File

@ -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."""