summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Shadura <andrew@shadura.me>2015-08-20 15:58:30 +0200
committerAndrew Shadura <andrew@shadura.me>2015-08-20 15:58:30 +0200
commitfec1da7e6ea8a3b3b03befa4ff8dd31d539f163d (patch)
treef349cf4e0bf6198660dfc1f0cfeec567b0bb84c5
parent25d6c405aff4167e801d0a4995083a56160b969e (diff)
Imported Upstream version 0.1.50+git20140603
-rw-r--r--Makefile1
-rw-r--r--reconfigure/__init__.py2
-rw-r--r--reconfigure/configs/__init__.py1
-rw-r--r--reconfigure/configs/csf.py17
-rw-r--r--reconfigure/includers/auto.py2
-rw-r--r--reconfigure/items/ajenti.py4
-rw-r--r--reconfigure/items/csf.py22
-rw-r--r--reconfigure/items/samba.py9
-rw-r--r--reconfigure/items/squid.py6
-rw-r--r--reconfigure/items/util.py3
-rw-r--r--reconfigure/parsers/__init__.py2
-rw-r--r--reconfigure/parsers/shell.py61
-rw-r--r--reconfigure/tests/configs/ajenti_tests.py1
-rw-r--r--reconfigure/tests/configs/csf_tests.py37
-rw-r--r--reconfigure/tests/configs/samba_tests.py24
-rw-r--r--reconfigure/tests/configs/supervisor_tests.py1
-rw-r--r--reconfigure/tests/parsers/shell_tests.py20
-rw-r--r--setup.py3
18 files changed, 200 insertions, 16 deletions
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*']),
)