Merge pull request #1889 from sebres/0.10-small-optim-review

0.10 small optimization & review, config-reader, pretty-dump, etc.
pull/1891/head
Serg G. Brester 2017-09-08 10:57:27 +02:00 committed by GitHub
commit 5221693ce0
7 changed files with 41 additions and 23 deletions

View File

@ -88,11 +88,11 @@ class ActionReader(DefinitionInitConfigReader):
stream.append(head + ["addaction", self._name]) stream.append(head + ["addaction", self._name])
multi = [] multi = []
for opt, optval in opts.iteritems(): for opt, optval in opts.iteritems():
if opt in self._configOpts: if opt in self._configOpts and not opt.startswith('known/'):
multi.append([opt, optval]) multi.append([opt, optval])
if self._initOpts: if self._initOpts:
for opt, optval in self._initOpts.iteritems(): for opt, optval in self._initOpts.iteritems():
if opt not in self._configOpts: if opt not in self._configOpts and not opt.startswith('known/'):
multi.append([opt, optval]) multi.append([opt, optval])
if len(multi) > 1: if len(multi) > 1:
stream.append(["multi-set", self._jailName, "action", self._name, multi]) stream.append(["multi-set", self._jailName, "action", self._name, multi])

View File

@ -20,8 +20,8 @@
# Author: Yaroslav Halchenko # Author: Yaroslav Halchenko
# Modified: Cyril Jaquier # Modified: Cyril Jaquier
__author__ = 'Yaroslav Halhenko' __author__ = 'Yaroslav Halhenko, Serg G. Brester (aka sebres)'
__copyright__ = 'Copyright (c) 2007 Yaroslav Halchenko' __copyright__ = 'Copyright (c) 2007 Yaroslav Halchenko, 2015 Serg G. Brester (aka sebres)'
__license__ = 'GPL' __license__ = 'GPL'
import os import os
@ -150,7 +150,7 @@ after = 1.conf
if seclwr == 'known': if seclwr == 'known':
# try get raw value from known options: # try get raw value from known options:
try: try:
v = self._sections['KNOWN'][opt] v = self._sections['KNOWN/'+section][opt]
except KeyError: except KeyError:
# fallback to default: # fallback to default:
try: try:
@ -297,7 +297,6 @@ after = 1.conf
# merge defaults and all sections to self: # merge defaults and all sections to self:
alld.update(cfg.get_defaults()) alld.update(cfg.get_defaults())
for n, s in cfg.get_sections().iteritems(): for n, s in cfg.get_sections().iteritems():
curalls = alls
# conditional sections # conditional sections
cond = SafeConfigParserWithIncludes.CONDITIONAL_RE.match(n) cond = SafeConfigParserWithIncludes.CONDITIONAL_RE.match(n)
if cond: if cond:
@ -313,7 +312,7 @@ after = 1.conf
s2 = alls.get(n) s2 = alls.get(n)
if isinstance(s2, dict): if isinstance(s2, dict):
# save previous known values, for possible using in local interpolations later: # save previous known values, for possible using in local interpolations later:
self.merge_section('KNOWN', s2, '') self.merge_section('KNOWN/'+n, s2, '')
# merge section # merge section
s2.update(s) s2.update(s)
else: else:

View File

@ -20,8 +20,8 @@
# Author: Cyril Jaquier # Author: Cyril Jaquier
# Modified by: Yaroslav Halchenko (SafeConfigParserWithIncludes) # Modified by: Yaroslav Halchenko (SafeConfigParserWithIncludes)
__author__ = "Cyril Jaquier" __author__ = "Cyril Jaquier, Yaroslav Halchenko, Serg G. Brester (aka sebres)"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2007 Yaroslav Halchenko, 2015 Serg G. Brester (aka sebres)"
__license__ = "GPL" __license__ = "GPL"
import glob import glob
@ -110,7 +110,7 @@ class ConfigReader():
def sections(self): def sections(self):
try: try:
return (n for n in self._cfg.sections() if n != 'KNOWN') return (n for n in self._cfg.sections() if not n.startswith('KNOWN/'))
except AttributeError: except AttributeError:
return [] return []

View File

@ -76,9 +76,9 @@ class Configurator:
self.__fail2ban.getOptions(updateMainOpt) self.__fail2ban.getOptions(updateMainOpt)
return self.__jails.getOptions(jail, ignoreWrong=ignoreWrong) return self.__jails.getOptions(jail, ignoreWrong=ignoreWrong)
def convertToProtocol(self): def convertToProtocol(self, allow_no_files=False):
self.__streams["general"] = self.__fail2ban.convert() self.__streams["general"] = self.__fail2ban.convert()
self.__streams["jails"] = self.__jails.convert() self.__streams["jails"] = self.__jails.convert(allow_no_files=allow_no_files)
def getConfigStream(self): def getConfigStream(self):
cmds = list() cmds = list()

View File

@ -102,6 +102,7 @@ class Fail2banCmdLine():
output(" --logtarget <FILE>|STDOUT|STDERR|SYSLOG") output(" --logtarget <FILE>|STDOUT|STDERR|SYSLOG")
output(" --syslogsocket auto|<FILE>") output(" --syslogsocket auto|<FILE>")
output(" -d dump configuration. For debugging") output(" -d dump configuration. For debugging")
output(" --dp, --dump-pretty dump the configuration using more human readable representation")
output(" -t, --test test configuration (can be also specified with start parameters)") output(" -t, --test test configuration (can be also specified with start parameters)")
output(" -i interactive mode") output(" -i interactive mode")
output(" -v increase verbosity") output(" -v increase verbosity")
@ -137,8 +138,8 @@ class Fail2banCmdLine():
self._conf["pidfile"] = opt[1] self._conf["pidfile"] = opt[1]
elif o.startswith("--log") or o.startswith("--sys"): elif o.startswith("--log") or o.startswith("--sys"):
self._conf[ o[2:] ] = opt[1] self._conf[ o[2:] ] = opt[1]
elif o == "-d": elif o in ["-d", "--dp", "--dump-pretty"]:
self._conf["dump"] = True self._conf["dump"] = True if o == "-d" else 2
elif o == "-t" or o == "--test": elif o == "-t" or o == "--test":
self.cleanConfOnly = True self.cleanConfOnly = True
self._conf["test"] = True self._conf["test"] = True
@ -184,7 +185,8 @@ class Fail2banCmdLine():
# Reads the command line options. # Reads the command line options.
try: try:
cmdOpts = 'hc:s:p:xfbdtviqV' cmdOpts = 'hc:s:p:xfbdtviqV'
cmdLongOpts = ['loglevel=', 'logtarget=', 'syslogsocket=', 'test', 'async', 'timeout=', 'str2sec=', 'help', 'version'] cmdLongOpts = ['loglevel=', 'logtarget=', 'syslogsocket=', 'test', 'async',
'timeout=', 'str2sec=', 'help', 'version', 'dp', '--dump-pretty']
optList, self._args = getopt.getopt(self._argv[1:], cmdOpts, cmdLongOpts) optList, self._args = getopt.getopt(self._argv[1:], cmdOpts, cmdLongOpts)
except getopt.GetoptError: except getopt.GetoptError:
self.dispUsage() self.dispUsage()
@ -240,7 +242,10 @@ class Fail2banCmdLine():
if readcfg: if readcfg:
ret, stream = self.readConfig() ret, stream = self.readConfig()
readcfg = False readcfg = False
self.dumpConfig(stream) if stream is not None:
self.dumpConfig(stream, self._conf["dump"] == 2)
else: # pragma: no cover
output("ERROR: The configuration stream failed because of the invalid syntax.")
if not self._conf.get("test", False): if not self._conf.get("test", False):
return ret return ret
@ -275,7 +280,8 @@ class Fail2banCmdLine():
self.configurator.readAll() self.configurator.readAll()
ret = self.configurator.getOptions(jail, self._conf, ret = self.configurator.getOptions(jail, self._conf,
ignoreWrong=not self.cleanConfOnly) ignoreWrong=not self.cleanConfOnly)
self.configurator.convertToProtocol() self.configurator.convertToProtocol(
allow_no_files=self._conf.get("dump", False))
stream = self.configurator.getConfigStream() stream = self.configurator.getConfigStream()
except Exception as e: except Exception as e:
logSys.error("Failed during configuration: %s" % e) logSys.error("Failed during configuration: %s" % e)
@ -283,9 +289,15 @@ class Fail2banCmdLine():
return ret, stream return ret, stream
@staticmethod @staticmethod
def dumpConfig(cmd): def dumpConfig(cmd, pretty=False):
if pretty:
from pprint import pformat
def _output(s):
output(pformat(s, width=1000, indent=2))
else:
_output = output
for c in cmd: for c in cmd:
output(c) _output(c)
return True return True
# #

View File

@ -235,9 +235,12 @@ class JailReader(ConfigReader):
found_files += 1 found_files += 1
stream.append( stream.append(
["set", self.__name, "addlogpath", p, tail]) ["set", self.__name, "addlogpath", p, tail])
if not (found_files or allow_no_files): if not found_files:
raise ValueError( msg = "Have not found any log file for %s jail" % self.__name
"Have not found any log file for %s jail" % self.__name) if not allow_no_files:
raise ValueError(msg)
logSys.warning(msg)
elif opt == "logencoding": elif opt == "logencoding":
stream.append(["set", self.__name, "logencoding", value]) stream.append(["set", self.__name, "logencoding", value])
elif opt == "backend": elif opt == "backend":

View File

@ -426,7 +426,11 @@ class Fail2banClientTest(Fail2banClientServerBase):
startparams = _start_params(tmp, True) startparams = _start_params(tmp, True)
self.execSuccess(startparams, "-vvd") self.execSuccess(startparams, "-vvd")
self.assertLogged("Loading files") self.assertLogged("Loading files")
self.assertLogged("logtarget") self.assertLogged("['set', 'logtarget',")
self.pruneLog()
# pretty dump:
self.execSuccess(startparams, "--dp")
self.assertLogged("['set', 'logtarget',")
@with_tmpdir @with_tmpdir
@with_kill_srv @with_kill_srv