From fec1da7e6ea8a3b3b03befa4ff8dd31d539f163d Mon Sep 17 00:00:00 2001 From: Andrew Shadura Date: Thu, 20 Aug 2015 15:58:30 +0200 Subject: Imported Upstream version 0.1.50+git20140603 --- Makefile | 1 + reconfigure/__init__.py | 2 +- reconfigure/configs/__init__.py | 1 + reconfigure/configs/csf.py | 17 ++++++++ reconfigure/includers/auto.py | 2 +- reconfigure/items/ajenti.py | 4 +- reconfigure/items/csf.py | 22 ++++++++++ reconfigure/items/samba.py | 9 ++-- reconfigure/items/squid.py | 6 +-- reconfigure/items/util.py | 3 +- reconfigure/parsers/__init__.py | 2 + reconfigure/parsers/shell.py | 61 +++++++++++++++++++++++++++ reconfigure/tests/configs/ajenti_tests.py | 1 + reconfigure/tests/configs/csf_tests.py | 37 ++++++++++++++++ reconfigure/tests/configs/samba_tests.py | 24 ++++++++--- reconfigure/tests/configs/supervisor_tests.py | 1 + reconfigure/tests/parsers/shell_tests.py | 20 +++++++++ setup.py | 3 ++ 18 files changed, 200 insertions(+), 16 deletions(-) create mode 100644 reconfigure/configs/csf.py create mode 100644 reconfigure/items/csf.py create mode 100644 reconfigure/parsers/shell.py create mode 100644 reconfigure/tests/configs/csf_tests.py create mode 100644 reconfigure/tests/parsers/shell_tests.py diff --git a/Makefile b/Makefile index 3575e77..0c6913b 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ PROJECT=reconfigure DEBPROJECT=python-reconfigure VERSION=`python -c "from reconfigure import __version__; print __version__"` PREFIX=/usr +PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin SPHINXOPTS = SPHINXBUILD = sphinx-build diff --git a/reconfigure/__init__.py b/reconfigure/__init__.py index 31b9658..a0036bc 100644 --- a/reconfigure/__init__.py +++ b/reconfigure/__init__.py @@ -1 +1 @@ -__version__ = "0.1.39" +__version__ = "0.1.50" diff --git a/reconfigure/configs/__init__.py b/reconfigure/configs/__init__.py index f0a6a26..9bc6b3a 100644 --- a/reconfigure/configs/__init__.py +++ b/reconfigure/configs/__init__.py @@ -7,6 +7,7 @@ from reconfigure.configs.ajenti import AjentiConfig from reconfigure.configs.bind9 import BIND9Config from reconfigure.configs.crontab import CrontabConfig from reconfigure.configs.ctdb import CTDBConfig, CTDBNodesConfig, CTDBPublicAddressesConfig +from reconfigure.configs.csf import CSFConfig from reconfigure.configs.dhcpd import DHCPDConfig from reconfigure.configs.exports import ExportsConfig from reconfigure.configs.fstab import FSTabConfig diff --git a/reconfigure/configs/csf.py b/reconfigure/configs/csf.py new file mode 100644 index 0000000..50a6915 --- /dev/null +++ b/reconfigure/configs/csf.py @@ -0,0 +1,17 @@ +from reconfigure.configs.base import Reconfig +from reconfigure.parsers import ShellParser +from reconfigure.builders import BoundBuilder +from reconfigure.items.csf import CSFData + + +class CSFConfig (Reconfig): + """ + ``CSF main config`` + """ + def __init__(self, **kwargs): + k = { + 'parser': ShellParser(), + 'builder': BoundBuilder(CSFData), + } + k.update(kwargs) + Reconfig.__init__(self, **k) diff --git a/reconfigure/includers/auto.py b/reconfigure/includers/auto.py index c220d88..b5ba35a 100644 --- a/reconfigure/includers/auto.py +++ b/reconfigure/includers/auto.py @@ -52,7 +52,7 @@ class AutoIncluder (BaseIncluder): else: if child.origin is None: child.origin = node.origin - elif child.origin != node.origin: + if child.origin != node.origin: node.children.remove(child) result.setdefault(child.origin, RootNode()).children.append(self.decompose_rec(child, result)) else: diff --git a/reconfigure/items/ajenti.py b/reconfigure/items/ajenti.py index ef70501..2a487f1 100644 --- a/reconfigure/items/ajenti.py +++ b/reconfigure/items/ajenti.py @@ -18,7 +18,8 @@ class SSLData (BoundData): class UserData (BoundData): def template(self): - return Node('unnamed', + return Node( + 'unnamed', PropertyNode('configs', {}), PropertyNode('password', ''), PropertyNode('permissions', []), @@ -48,6 +49,7 @@ SSLData.bind_property('enable', 'enable') ConfigData.bind_name('name') UserData.bind_name('name') +UserData.bind_property('email', 'email') UserData.bind_property('password', 'password') UserData.bind_property('permissions', 'permissions') UserData.bind_collection('configs', lambda x: x.get('configs'), item_class=ConfigData, collection_class=BoundDictionary, key=lambda x: x.name) diff --git a/reconfigure/items/csf.py b/reconfigure/items/csf.py new file mode 100644 index 0000000..fb3767f --- /dev/null +++ b/reconfigure/items/csf.py @@ -0,0 +1,22 @@ +from reconfigure.nodes import Node, PropertyNode +from reconfigure.items.bound import BoundData +from reconfigure.items.util import onezero_getter, onezero_setter + + +class CSFData (BoundData): + pass + + +CSFData.bind_property('TESTING', 'testing', getter=onezero_getter, setter=onezero_setter) +CSFData.bind_property('IPV6', 'ipv6', getter=onezero_getter, setter=onezero_setter) + +CSFData.bind_property('TCP_IN', 'tcp_in') +CSFData.bind_property('TCP_OUT', 'tcp_out') +CSFData.bind_property('UDP_IN', 'udp_in') +CSFData.bind_property('UDP_OUT', 'udp_out') +CSFData.bind_property('TCP6_IN', 'tcp6_in') +CSFData.bind_property('TCP6_OUT', 'tcp6_out') +CSFData.bind_property('UDP6_IN', 'udp6_in') +CSFData.bind_property('UDP6_OUT', 'udp6_out') +CSFData.bind_property('ETH_DEVICE', 'eth_device') +CSFData.bind_property('ETH6_DEVICE', 'eth6_device') diff --git a/reconfigure/items/samba.py b/reconfigure/items/samba.py index 01b6f6f..7d9308d 100644 --- a/reconfigure/items/samba.py +++ b/reconfigure/items/samba.py @@ -15,15 +15,18 @@ class ShareData (BoundData): fields = [ 'comment', 'path', 'guest ok', 'browseable', 'create mask', 'directory mask', 'read only', 'follow symlinks', 'wide links', 'fstype', 'write list', 'veto files', - 'force create mode', 'force directory mode', + 'force create mode', 'force directory mode', 'dfree command', 'force user', 'force group', + 'valid users', 'read list', 'dfree cache time', ] defaults = [ '', '', 'no', 'yes', '0744', '0755', 'yes', - 'yes', 'no', 'NTFS', '', '', '000', '000', + 'yes', 'no', 'NTFS', '', '', '000', '000', '', + '', '', '', '', '', ] default_values = [ '', '', False, True, '0744', '0755', True, - True, False, '', '', '', '000', '000', + True, False, '', '', '', '000', '000', '', + '', '', '', '', '', ] def template(self): diff --git a/reconfigure/items/squid.py b/reconfigure/items/squid.py index 2504b55..92edbbf 100644 --- a/reconfigure/items/squid.py +++ b/reconfigure/items/squid.py @@ -7,7 +7,7 @@ class SquidData (BoundData): class ACLData (BoundData): - def template(self, name, *args): + def template(self, name=None, *args): children = [PropertyNode('1', name)] index = 2 for arg in args: @@ -54,8 +54,8 @@ class HTTPSPortData (BoundData): class ArgumentData (BoundData): - def template(self, *args): - return PropertyNode(*args) + def template(self): + return PropertyNode('value', 'none') def __bind_by_name(cls, prop, name, itemcls): diff --git a/reconfigure/items/util.py b/reconfigure/items/util.py index 0a615ed..adb0902 100644 --- a/reconfigure/items/util.py +++ b/reconfigure/items/util.py @@ -1,3 +1,4 @@ yn_getter = lambda x: x == 'yes' - yn_setter = lambda x: 'yes' if x else 'no' +onezero_getter = lambda x: x == '1' +onezero_setter = lambda x: '1' if x else '0' diff --git a/reconfigure/parsers/__init__.py b/reconfigure/parsers/__init__.py index af88033..c8a2dfb 100644 --- a/reconfigure/parsers/__init__.py +++ b/reconfigure/parsers/__init__.py @@ -6,6 +6,7 @@ from reconfigure.parsers.iptables import IPTablesParser from reconfigure.parsers.jsonparser import JsonParser from reconfigure.parsers.nginx import NginxParser from reconfigure.parsers.nsd import NSDParser +from reconfigure.parsers.shell import ShellParser from reconfigure.parsers.ssv import SSVParser from reconfigure.parsers.squid import SquidParser from reconfigure.parsers.crontab import CrontabParser @@ -20,6 +21,7 @@ __all__ = [ 'JsonParser', 'NginxParser', 'NSDParser', + 'ShellParser', 'SSVParser', 'SquidParser', ] diff --git a/reconfigure/parsers/shell.py b/reconfigure/parsers/shell.py new file mode 100644 index 0000000..c151a64 --- /dev/null +++ b/reconfigure/parsers/shell.py @@ -0,0 +1,61 @@ +from reconfigure.nodes import * +from reconfigure.parsers import BaseParser + + +class ShellParser (BaseParser): + """ + A parser for shell scripts with variables + """ + + def __init__(self, *args, **kwargs): + self.comment = '#' + self.continuation = '\\' + BaseParser.__init__(self, *args, **kwargs) + + def parse(self, content): + rawlines = content.splitlines() + lines = [] + while rawlines: + l = rawlines.pop(0).strip() + while self.continuation and rawlines and l.endswith(self.continuation): + l = l[:-len(self.continuation)] + l += rawlines.pop(0) + lines.append(l) + + root = RootNode() + last_comment = None + for line in lines: + line = line.strip() + if line: + if line.startswith(self.comment): + c = line.strip(self.comment).strip() + if last_comment: + last_comment += '\n' + c + else: + last_comment = c + continue + if len(line) == 0: + continue + + name, value = line.split('=', 1) + comment = None + if '#' in value: + value, comment = value.split('#', 1) + last_comment = (last_comment or '') + comment.strip() + node = PropertyNode(name.strip(), value.strip().strip('"')) + if last_comment: + node.comment = last_comment + last_comment = None + root.append(node) + return root + + def stringify(self, tree): + r = '' + for node in tree.children: + if node.comment and '\n' in node.comment: + r += '\n' + ''.join('# %s\n' % x for x in node.comment.splitlines()) + r += '%s="%s"' % (node.name, node.value) + if node.comment and not '\n' in node.comment: + r += ' # %s' % node.comment + r += '\n' + return r diff --git a/reconfigure/tests/configs/ajenti_tests.py b/reconfigure/tests/configs/ajenti_tests.py index 66a0526..aa1374b 100644 --- a/reconfigure/tests/configs/ajenti_tests.py +++ b/reconfigure/tests/configs/ajenti_tests.py @@ -40,6 +40,7 @@ class AjentiConfigTest (BaseConfigTest): 'ssl': {'certificate_path': '', 'enable': False}, 'users': {'test': { 'configs': {'a': {'data': {}, 'name': 'a'}}, + 'email': None, 'name': 'test', 'password': 'sha512', 'permissions': ['section:Dash'] diff --git a/reconfigure/tests/configs/csf_tests.py b/reconfigure/tests/configs/csf_tests.py new file mode 100644 index 0000000..1d60c27 --- /dev/null +++ b/reconfigure/tests/configs/csf_tests.py @@ -0,0 +1,37 @@ +from reconfigure.configs import CSFConfig +from reconfigure.tests.configs.base_test import BaseConfigTest + + +class CSFConfigTest (BaseConfigTest): + sources = { + None: """ +TESTING="1" +TCP_IN="20,21,22,25,53,80,110,143,443,465,587,993,995" +TCP_OUT="20,21,22,25,53,80,110,113,443" +UDP_IN="20,21,53" +UDP_OUT="20,21,53,113,123" +IPV6="0" +TCP6_IN="20,21,22,25,53,80,110,143,443,465,587,993,995" +TCP6_OUT="20,21,22,25,53,80,110,113,443" +UDP6_IN="20,21,53" +UDP6_OUT="20,21,53,113,123" +ETH_DEVICE="" +ETH6_DEVICE="" +""" + } + result = { + "tcp6_out": "20,21,22,25,53,80,110,113,443", + "testing": True, + "eth_device": "", + "tcp_in": "20,21,22,25,53,80,110,143,443,465,587,993,995", + "tcp6_in": "20,21,22,25,53,80,110,143,443,465,587,993,995", + "udp6_in": "20,21,53", + "tcp_out": "20,21,22,25,53,80,110,113,443", + "udp6_out": "20,21,53,113,123", + "ipv6": False, + "udp_in": "20,21,53", + "eth6_device": "", + "udp_out": "20,21,53,113,123" + } + + config = CSFConfig diff --git a/reconfigure/tests/configs/samba_tests.py b/reconfigure/tests/configs/samba_tests.py index 7a5865c..2604639 100644 --- a/reconfigure/tests/configs/samba_tests.py +++ b/reconfigure/tests/configs/samba_tests.py @@ -49,10 +49,16 @@ directory mask=0700 "path": "", 'wide_links': False, "fstype": "", - "force_create_mode": "000", + "force_create_mode": "000", "force_directory_mode": "000", - "veto_files": "", - "write_list": "", + "veto_files": "", + "write_list": "", + "dfree_command": "", + "force_group": "", + "force_user": "", + "valid_users": "", + "read_list": "", + "dfree_cache_time": "", }, { "name": "profiles", @@ -66,10 +72,16 @@ directory mask=0700 "path": "/home/samba/profiles", 'wide_links': False, "fstype": "", - "force_create_mode": "000", + "force_create_mode": "000", "force_directory_mode": "000", - "veto_files": "", - "write_list": "", + "veto_files": "", + "write_list": "", + "dfree_command": "", + "force_group": "", + "force_user": "", + "valid_users": "", + "read_list": "", + "dfree_cache_time": "", } ] } diff --git a/reconfigure/tests/configs/supervisor_tests.py b/reconfigure/tests/configs/supervisor_tests.py index b304654..644f78a 100644 --- a/reconfigure/tests/configs/supervisor_tests.py +++ b/reconfigure/tests/configs/supervisor_tests.py @@ -16,6 +16,7 @@ command=cat result = { "programs": [ { + "comment": None, "autorestart": None, "name": "test1", "startsecs": None, diff --git a/reconfigure/tests/parsers/shell_tests.py b/reconfigure/tests/parsers/shell_tests.py new file mode 100644 index 0000000..8578d2e --- /dev/null +++ b/reconfigure/tests/parsers/shell_tests.py @@ -0,0 +1,20 @@ +from reconfigure.tests.parsers.base_test import BaseParserTest +from reconfigure.parsers import ShellParser +from reconfigure.nodes import * + + +class ShellParserTest (BaseParserTest): + parser = ShellParser() + source = """ +# The following +# otherwise they +PORTS_pop3d="110,995" +PORTS_htpasswd="80,443" # b +""" + parsed = RootNode( + None, + PropertyNode('PORTS_pop3d', '110,995', comment='The following\notherwise they'), + PropertyNode('PORTS_htpasswd', '80,443', comment='b'), + ) + +del BaseParserTest diff --git a/setup.py b/setup.py index 0c40876..2795e33 100644 --- a/setup.py +++ b/setup.py @@ -15,5 +15,8 @@ setup( author='Eugeny Pankov', author_email='e@ajenti.org', url='http://ajenti.org/', + classifiers=[ + "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)", + ], packages=find_packages(exclude=['*test*']), ) -- cgit v1.2.3