mirror of https://github.com/fail2ban/fail2ban
SafeConfigParserWithIncludes: fixed read of included config-files (expands with localized version, so `inc.local` overwrites options of `inc.conf` for config-files included with before/after);
added new test to cover this case.pull/2306/head
parent
555b29e8e6
commit
0245777c84
|
@ -73,6 +73,17 @@ else: # pragma: no cover
|
||||||
return self._cp_interpolate_some(option, accum, rest, section, map, *args, **kwargs)
|
return self._cp_interpolate_some(option, accum, rest, section, map, *args, **kwargs)
|
||||||
SafeConfigParser._interpolate_some = _interpolate_some
|
SafeConfigParser._interpolate_some = _interpolate_some
|
||||||
|
|
||||||
|
def _expandConfFilesWithLocal(filenames):
|
||||||
|
"""Expands config files with local extension.
|
||||||
|
"""
|
||||||
|
newFilenames = []
|
||||||
|
for filename in filenames:
|
||||||
|
newFilenames.append(filename)
|
||||||
|
localname = os.path.splitext(filename)[0] + '.local'
|
||||||
|
if localname not in filenames and os.path.isfile(localname):
|
||||||
|
newFilenames.append(localname)
|
||||||
|
return newFilenames
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
logLevel = 7
|
logLevel = 7
|
||||||
|
@ -245,6 +256,7 @@ after = 1.conf
|
||||||
def _getIncludes(self, filenames, seen=[]):
|
def _getIncludes(self, filenames, seen=[]):
|
||||||
if not isinstance(filenames, list):
|
if not isinstance(filenames, list):
|
||||||
filenames = [ filenames ]
|
filenames = [ filenames ]
|
||||||
|
filenames = _expandConfFilesWithLocal(filenames)
|
||||||
# retrieve or cache include paths:
|
# retrieve or cache include paths:
|
||||||
if self._cfg_share:
|
if self._cfg_share:
|
||||||
# cache/share include list:
|
# cache/share include list:
|
||||||
|
|
|
@ -28,7 +28,8 @@ import re
|
||||||
import shutil
|
import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
from ..client.configreader import ConfigReader, ConfigReaderUnshared, NoSectionError
|
from ..client.configreader import ConfigReader, ConfigReaderUnshared, \
|
||||||
|
DefinitionInitConfigReader, NoSectionError
|
||||||
from ..client import configparserinc
|
from ..client import configparserinc
|
||||||
from ..client.jailreader import JailReader, extractOptions
|
from ..client.jailreader import JailReader, extractOptions
|
||||||
from ..client.filterreader import FilterReader
|
from ..client.filterreader import FilterReader
|
||||||
|
@ -125,6 +126,54 @@ option = %s
|
||||||
self._remove("c.d/90.conf")
|
self._remove("c.d/90.conf")
|
||||||
self.assertEqual(self._getoption(), 2)
|
self.assertEqual(self._getoption(), 2)
|
||||||
|
|
||||||
|
def testLocalInIncludes(self):
|
||||||
|
self._write("c.conf", value=None, content="""
|
||||||
|
[INCLUDES]
|
||||||
|
before = ib.conf
|
||||||
|
after = ia.conf
|
||||||
|
[Definition]
|
||||||
|
test = %(default/test)s
|
||||||
|
""")
|
||||||
|
self._write("ib.conf", value=None, content="""
|
||||||
|
[DEFAULT]
|
||||||
|
test = A
|
||||||
|
[Definition]
|
||||||
|
option = 1
|
||||||
|
""")
|
||||||
|
self._write("ib.local", value=None, content="""
|
||||||
|
[DEFAULT]
|
||||||
|
test = B
|
||||||
|
[Definition]
|
||||||
|
option = 2
|
||||||
|
""")
|
||||||
|
self._write("ia.conf", value=None, content="""
|
||||||
|
[DEFAULT]
|
||||||
|
test = C
|
||||||
|
[Definition]
|
||||||
|
oafter = 3
|
||||||
|
""")
|
||||||
|
self._write("ia.local", value=None, content="""
|
||||||
|
[DEFAULT]
|
||||||
|
test = D
|
||||||
|
[Definition]
|
||||||
|
oafter = 4
|
||||||
|
""")
|
||||||
|
class TestDefConfReader(DefinitionInitConfigReader):
|
||||||
|
_configOpts = {
|
||||||
|
"option": ["int", None],
|
||||||
|
"oafter": ["int", None],
|
||||||
|
"test": ["string", None],
|
||||||
|
}
|
||||||
|
self.c = TestDefConfReader('c', 'option', {})
|
||||||
|
self.c.setBaseDir(self.d)
|
||||||
|
self.assertTrue(self.c.read())
|
||||||
|
self.c.getOptions({}, all=True)
|
||||||
|
o = self.c.getCombined()
|
||||||
|
# test local wins (overwrite all options):
|
||||||
|
self.assertEqual(o.get('option'), 2)
|
||||||
|
self.assertEqual(o.get('oafter'), 4)
|
||||||
|
self.assertEqual(o.get('test'), 'D')
|
||||||
|
|
||||||
def testInterpolations(self):
|
def testInterpolations(self):
|
||||||
self.assertFalse(self.c.read('i')) # nothing is there yet
|
self.assertFalse(self.c.read('i')) # nothing is there yet
|
||||||
self._write("i.conf", value=None, content="""
|
self._write("i.conf", value=None, content="""
|
||||||
|
|
Loading…
Reference in New Issue