mirror of https://github.com/fail2ban/fail2ban
filter/action (and its includes): substitution `%(param)s` may be used now (instead of `<param>`) for init-values specified in jail-configs via `action[param1="...", param2=...]`;
substitution `<param>` should be used for dynamic interpolation only (todo: review configurations to replace it);pull/1622/head
parent
b856e1dadc
commit
097970781c
|
@ -29,7 +29,7 @@ import re
|
||||||
import sys
|
import sys
|
||||||
from ..helpers import getLogger
|
from ..helpers import getLogger
|
||||||
|
|
||||||
if sys.version_info >= (3,2): # pragma: no cover
|
if sys.version_info >= (3,2):
|
||||||
|
|
||||||
# SafeConfigParser deprecated from Python 3.2 (renamed to ConfigParser)
|
# SafeConfigParser deprecated from Python 3.2 (renamed to ConfigParser)
|
||||||
from configparser import ConfigParser as SafeConfigParser, \
|
from configparser import ConfigParser as SafeConfigParser, \
|
||||||
|
|
|
@ -28,13 +28,25 @@ import glob
|
||||||
import os
|
import os
|
||||||
from ConfigParser import NoOptionError, NoSectionError
|
from ConfigParser import NoOptionError, NoSectionError
|
||||||
|
|
||||||
from .configparserinc import SafeConfigParserWithIncludes, logLevel
|
from .configparserinc import sys, SafeConfigParserWithIncludes, logLevel
|
||||||
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__)
|
||||||
|
|
||||||
|
|
||||||
|
# if sys.version_info >= (3,5):
|
||||||
|
# def _merge_dicts(x, y):
|
||||||
|
# return {**x, **y}
|
||||||
|
# else:
|
||||||
|
def _merge_dicts(x, y):
|
||||||
|
r = x
|
||||||
|
if y:
|
||||||
|
r = x.copy()
|
||||||
|
r.update(y)
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
class ConfigReader():
|
class ConfigReader():
|
||||||
"""Generic config reader class.
|
"""Generic config reader class.
|
||||||
|
|
||||||
|
@ -127,9 +139,9 @@ class ConfigReader():
|
||||||
return self._cfg.options(*args)
|
return self._cfg.options(*args)
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def get(self, sec, opt):
|
def get(self, sec, opt, raw=False, vars={}):
|
||||||
if self._cfg is not None:
|
if self._cfg is not None:
|
||||||
return self._cfg.get(sec, opt)
|
return self._cfg.get(sec, opt, raw, vars)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def getOptions(self, *args, **kwargs):
|
def getOptions(self, *args, **kwargs):
|
||||||
|
@ -210,6 +222,8 @@ class ConfigReaderUnshared(SafeConfigParserWithIncludes):
|
||||||
|
|
||||||
def getOptions(self, sec, options, pOptions=None, shouldExist=False):
|
def getOptions(self, sec, options, pOptions=None, shouldExist=False):
|
||||||
values = dict()
|
values = dict()
|
||||||
|
if pOptions is None:
|
||||||
|
pOptions = {}
|
||||||
for optname in options:
|
for optname in options:
|
||||||
if isinstance(options, (list,tuple)):
|
if isinstance(options, (list,tuple)):
|
||||||
if len(optname) > 2:
|
if len(optname) > 2:
|
||||||
|
@ -218,15 +232,15 @@ class ConfigReaderUnshared(SafeConfigParserWithIncludes):
|
||||||
(opttype, optname), optvalue = optname, None
|
(opttype, optname), optvalue = optname, None
|
||||||
else:
|
else:
|
||||||
opttype, optvalue = options[optname]
|
opttype, optvalue = options[optname]
|
||||||
|
if optname in pOptions:
|
||||||
|
continue
|
||||||
try:
|
try:
|
||||||
if opttype == "bool":
|
if opttype == "bool":
|
||||||
v = self.getboolean(sec, optname)
|
v = self.getboolean(sec, optname)
|
||||||
elif opttype == "int":
|
elif opttype == "int":
|
||||||
v = self.getint(sec, optname)
|
v = self.getint(sec, optname)
|
||||||
else:
|
else:
|
||||||
v = self.get(sec, optname)
|
v = self.get(sec, optname, vars=pOptions)
|
||||||
if not pOptions is None and optname in pOptions:
|
|
||||||
continue
|
|
||||||
values[optname] = v
|
values[optname] = v
|
||||||
except NoSectionError as e:
|
except NoSectionError as e:
|
||||||
if shouldExist:
|
if shouldExist:
|
||||||
|
@ -289,6 +303,12 @@ class DefinitionInitConfigReader(ConfigReader):
|
||||||
return SafeConfigParserWithIncludes.read(self._cfg, self._file)
|
return SafeConfigParserWithIncludes.read(self._cfg, self._file)
|
||||||
|
|
||||||
def getOptions(self, pOpts):
|
def getOptions(self, pOpts):
|
||||||
|
# overwrite static definition options with init values, supplied as
|
||||||
|
# direct parameters from jail-config via action[xtra1="...", xtra2=...]:
|
||||||
|
if self._initOpts:
|
||||||
|
if not pOpts:
|
||||||
|
pOpts = dict()
|
||||||
|
pOpts = _merge_dicts(pOpts, self._initOpts)
|
||||||
self._opts = ConfigReader.getOptions(
|
self._opts = ConfigReader.getOptions(
|
||||||
self, "Definition", self._configOpts, pOpts)
|
self, "Definition", self._configOpts, pOpts)
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ __license__ = "GPL"
|
||||||
import os
|
import os
|
||||||
import shlex
|
import shlex
|
||||||
|
|
||||||
from .configreader import DefinitionInitConfigReader
|
from .configreader import DefinitionInitConfigReader, _merge_dicts
|
||||||
from ..server.action import CommandAction
|
from ..server.action import CommandAction
|
||||||
from ..helpers import getLogger
|
from ..helpers import getLogger
|
||||||
|
|
||||||
|
@ -50,7 +50,9 @@ class FilterReader(DefinitionInitConfigReader):
|
||||||
return self.__file
|
return self.__file
|
||||||
|
|
||||||
def getCombined(self):
|
def getCombined(self):
|
||||||
combinedopts = dict(list(self._opts.items()) + list(self._initOpts.items()))
|
combinedopts = self._opts
|
||||||
|
if self._initOpts:
|
||||||
|
combinedopts = _merge_dicts(self._opts, self._initOpts)
|
||||||
if not len(combinedopts):
|
if not len(combinedopts):
|
||||||
return {}
|
return {}
|
||||||
opts = CommandAction.substituteRecursiveTags(combinedopts)
|
opts = CommandAction.substituteRecursiveTags(combinedopts)
|
||||||
|
|
Loading…
Reference in New Issue