Branch 'dev/confmgmt' - 8 commits - pykolab/cli pykolab/imap pykolab/plugins pykolab/setup share/templates ucs/kolab_sieve.py
Jeroen van Meeuwen
vanmeeuwen at kolabsys.com
Fri Dec 14 13:38:12 CET 2012
pykolab/cli/sieve/cmd_refresh.py | 4 ++--
pykolab/imap/__init__.py | 4 ++++
pykolab/plugins/sievemgmt/__init__.py | 4 ++--
pykolab/setup/setup_mta.py | 3 +++
pykolab/setup/setup_roundcube.py | 1 +
share/templates/roundcubemail/main.inc.php.tpl | 2 +-
ucs/kolab_sieve.py | 1 +
7 files changed, 14 insertions(+), 5 deletions(-)
New commits:
commit a6a97459fc5e81c3b0001052bb1b4bce5dcba6e1
Merge: a9b1d3f a7d87ec
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date: Fri Dec 14 12:38:05 2012 +0000
Merge remote-tracking branch 'origin/dev/confmgmt' into dev/confmgmt
commit a9b1d3f731e05f0b4d49a681483e73728d5f9aca
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date: Fri Dec 14 10:57:38 2012 +0000
Add conf command group
diff --git a/pykolab/cli/conf/__init__.py b/pykolab/cli/conf/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/pykolab/cli/conf/cmd_add_role.py b/pykolab/cli/conf/cmd_add_role.py
new file mode 100644
index 0000000..7b0076f
--- /dev/null
+++ b/pykolab/cli/conf/cmd_add_role.py
@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import sys
+import time
+
+import pykolab
+
+from pykolab import confmgmt
+from pykolab import constants
+from pykolab.cli import commands
+from pykolab.confmgmt.db import get_db
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.cli')
+conf = pykolab.getConf()
+
+def __init__():
+ commands.register('add_role', execute, group='conf', description=description())
+
+def cli_options():
+ my_option_group = conf.add_cli_parser_option_group(_("CLI Options"))
+ my_option_group.add_option(
+ '--role',
+ dest = "role",
+ action = "store",
+ default = None,
+ metavar = "ROLE",
+ help = _("Add role ROLE.")
+ )
+
+def description():
+ return """Add a role."""
+
+def execute(*args, **kw):
+ if conf.role == None:
+ try:
+ conf.role = conf.cli_args.pop(0)
+ except IndexError, errmsg:
+ print >> sys.stderr, _("Specify a role to add")
+ sys.exit(1)
+
+ role = confmgmt.add_role(conf.role)
diff --git a/pykolab/cli/conf/cmd_file_add_setting.py b/pykolab/cli/conf/cmd_file_add_setting.py
new file mode 100644
index 0000000..e90e2e8
--- /dev/null
+++ b/pykolab/cli/conf/cmd_file_add_setting.py
@@ -0,0 +1,127 @@
+# -*- coding: utf-8 -*-
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import sys
+import time
+
+import pykolab
+
+from pykolab import confmgmt
+from pykolab import constants
+from pykolab.cli import commands
+from pykolab.confmgmt.db import get_db
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.cli')
+conf = pykolab.getConf()
+
+def __init__():
+ commands.register('file_add_setting', execute, group='conf', description=description())
+
+def cli_options():
+ my_option_group = conf.add_cli_parser_option_group(_("CLI Options"))
+ my_option_group.add_option(
+ '--file',
+ dest = "_file",
+ action = "store",
+ default = None,
+ metavar = "FILE",
+ help = _("Add file FILE")
+ )
+
+ my_option_group.add_option(
+ '--role',
+ dest = "roles",
+ action = "append",
+ default = [],
+ metavar = "ROLE",
+ help = _("Exclusively associate the setting for file FILE with role ROLE. May be specified multiple times to associate the file setting with multiple roles.")
+ )
+
+ my_option_group.add_option(
+ '--key',
+ dest = "key",
+ action = "store",
+ default = None,
+ metavar = "KEY",
+ help = _("The key or 'name' for the setting.")
+ )
+
+ my_option_group.add_option(
+ '--value',
+ dest = "value",
+ action = "store",
+ default = None,
+ metavar = "VALUE",
+ help = _("Set to value VALUE.")
+ )
+
+ my_option_group.add_option(
+ '--function',
+ dest = "function",
+ action = "store",
+ default = None,
+ metavar = "FUNCTION",
+ help = _("Set to function FUNCTION.")
+ )
+
+def description():
+ return """Add a managed setting with key KEY in file FILE."""
+
+def execute(*args, **kw):
+ if conf._file == None:
+ print >> sys.stderr, _("Must specify a file.")
+ sys.exit(1)
+
+ if conf.key == None:
+ print >> sys.stderr, _("Must specify a key.")
+ sys.exit(1)
+
+ if conf.value == None and conf.function == None:
+ print >> sys.stderr, _("Must specify a value of a function to get the values with.")
+ sys.exit(1)
+
+ if not conf.value == None and not conf.function == None:
+ print >> sys.stderr, _("Can only specify one of value or function.")
+ sys.exit(1)
+
+ _file = confmgmt.get_file(conf._file)
+
+ if _file == None:
+ print >> sys.stderr, _("File %s does not exist.") % (conf._file)
+ sys.exit(1)
+
+ if conf.key in [x.key for x in _file.settings]:
+ print >> sys.stderr, _("Setting with key %s already managed in file %s") % (conf.key, conf._file)
+ sys.exit(1)
+
+ setting = confmgmt.add_setting(conf.key, conf.value, conf.function)
+
+ _file.settings.append(setting)
+
+ for role_name in conf.roles:
+ role = confmgmt.get_role(role_name)
+
+ if role == None:
+ log.warning(_("Role %s does not exist.") % (role_name))
+ continue
+
+ setting.roles.append(role)
+
+ confmgmt.commit()
diff --git a/pykolab/cli/conf/cmd_file_apply_settings.py b/pykolab/cli/conf/cmd_file_apply_settings.py
new file mode 100644
index 0000000..cfeb481
--- /dev/null
+++ b/pykolab/cli/conf/cmd_file_apply_settings.py
@@ -0,0 +1,172 @@
+# -*- coding: utf-8 -*-
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+from augeas import Augeas
+from Cheetah.Template import Template
+
+import sys
+import time
+
+import pykolab
+
+from pykolab import confmgmt
+from pykolab import constants
+from pykolab.cli import commands
+from pykolab.confmgmt.db import get_db
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.cli')
+conf = pykolab.getConf()
+
+def __init__():
+ commands.register('file_apply_settings', execute, group='conf', description=description())
+
+def cli_options():
+ my_option_group = conf.add_cli_parser_option_group(_("CLI Options"))
+ my_option_group.add_option(
+ '--file',
+ dest = "_file",
+ action = "store",
+ default = None,
+ metavar = "FILE",
+ help = _("Add file FILE")
+ )
+
+def description():
+ return """Apply managed settings to file FILE."""
+
+def execute(*args, **kw):
+ if conf._file == None:
+ print >> sys.stderr, _("Must specify a file.")
+ sys.exit(1)
+
+ _file = confmgmt.get_file(conf._file)
+
+ if _file == None:
+ print >> sys.stderr, _("File %s is not managed.") % (conf._file)
+ sys.exit(1)
+
+ if len(_file.settings) < 1:
+ print >> sys.stderr, _("No managed settings for file %s.") % (conf._file)
+ sys.exit(1)
+
+ node = confmgmt.get_node(constants.fqdn)
+
+ if node == None:
+ print >> sys.stderr, _("This node (%s) is not managed.") % (constants.fqdn)
+ sys.exit(1)
+
+ myaugeas = Augeas()
+ myaugeas.set('/augeas/load/Postfix_LDAP/lens', '@Postfix_Main')
+ myaugeas.set('/augeas/load/Postfix_LDAP/incl', "/etc/postfix/ldap/*.cf")
+ myaugeas.load()
+
+ for role in node.roles:
+ #print role
+ for service in role.services:
+ #print service
+ for _file in service.files:
+ #print _file
+ if _file.path == conf._file:
+ _cheetah_searchlist = {}
+ for setting in _file.settings:
+ #print "node role names", [haystack.name for haystack in node.roles]
+ #print "setting role names", [needle.name for needle in setting.roles]
+ #print [needle.name for needle in setting.roles if needle.name in [haystack.name for haystack in node.roles]]
+ if len(setting.roles) > 0:
+ if (len([needle.name for needle in setting.roles if needle.name in [haystack.name for haystack in node.roles]]) > 0):
+ if not setting.function == None:
+ exec("retval = %s" % (setting.function))
+ if isinstance(retval, list):
+ new_setting = ' '.join(retval)
+ else:
+ new_setting = retval
+
+ if _file.tech == 'augeas':
+ current_value = myaugeas.get('/files%s/%s' % (_file.path, setting.key))
+ if not new_setting == current_value:
+ myaugeas.set('/files%s/%s' % (_file.path, setting.key), new_setting)
+ elif _file.tech == 'cheetah':
+ _cheetah_searchlist[setting.key] = new_setting
+
+ else:
+ if _file.tech == 'augeas':
+ current_value = myaugeas.get('/files%s/%s' % (_file.path, setting.key))
+ if not setting.value == current_value:
+ myaugeas.set('/files%s/%s' % (_file.path, setting.key), setting.value)
+ elif _file.tech == 'cheetah':
+ _cheetah_searchlist[setting.key] = setting.value
+ else:
+ if not setting.function == None:
+ exec("retval = %s" % (setting.function))
+ if isinstance(retval, list):
+ new_setting = ' '.join(retval)
+ else:
+ new_setting = retval
+
+ if _file.tech == 'augeas':
+ current_value = myaugeas.get('/files%s/%s' % (_file.path, setting.key))
+ if not new_setting == current_value:
+ myaugeas.set('/files%s/%s' % (_file.path, setting.key), new_setting)
+ elif _file.tech == 'cheetah':
+ _cheetah_searchlist[setting.key] = new_setting
+
+ else:
+ if _file.tech == 'augeas':
+ current_value = myaugeas.get('/files%s/%s' % (_file.path, setting.key))
+ if not setting.value == current_value:
+ myaugeas.set('/files%s/%s' % (_file.path, setting.key), setting.value)
+ elif _file.tech == 'cheetah':
+ _cheetah_searchlist[setting.key] = setting.value
+
+ if _file.tech == 'cheetah':
+ _cheetah_searchlist['conf'] = conf
+
+ _file_basename = os.path.basename(_file.path)
+ if os.path.isfile('/etc/kolab/templates/roundcubemail/%s.tpl' % (_file_basename)):
+ template_file = '/etc/kolab/templates/roundcubemail/%s.tpl' % (_file_basename)
+ elif os.path.isfile('/usr/share/kolab/templates/roundcubemail/%s.tpl' % (_file_basename)):
+ template_file = '/usr/share/kolab/templates/roundcubemail/%s.tpl' % (_file_basename)
+ elif os.path.isfile(os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'roundcubemail', '%s.tpl' % (_file_basename)))):
+ template_file = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'roundcubemail', '%s.tpl' % (_file_basename)))
+
+ if not template_file == None:
+ log.debug(_("Using template file %r") % (template_file), level=8)
+ fp = open(template_file, 'r')
+ template_definition = fp.read()
+ fp.close()
+
+ t = Template(template_definition, searchList=[_cheetah_searchlist])
+
+ print t.__dict__
+ print "Settings:", t._CHEETAH_requiredCheetahMethods
+
+ log.debug(
+ _("Successfully compiled template %r, writing out to %r") % (
+ template_file,
+ '/etc/roundcubemail/%s' % (_file_basename)
+ ),
+ level=8
+ )
+
+ fp = open('/etc/roundcubemail/%s.new' % (_file_basename), 'w')
+ fp.write(t.__str__())
+ fp.close()
+ else:
+ myaugeas.save()
diff --git a/pykolab/cli/conf/cmd_file_list_settings.py b/pykolab/cli/conf/cmd_file_list_settings.py
new file mode 100644
index 0000000..9fc9045
--- /dev/null
+++ b/pykolab/cli/conf/cmd_file_list_settings.py
@@ -0,0 +1,80 @@
+# -*- coding: utf-8 -*-
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import sys
+import time
+
+import pykolab
+
+from pykolab import confmgmt
+from pykolab import constants
+from pykolab.cli import commands
+from pykolab.confmgmt.db import get_db
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.cli')
+conf = pykolab.getConf()
+
+def __init__():
+ commands.register('file_list_settings', execute, group='conf', description=description())
+
+def cli_options():
+ my_option_group = conf.add_cli_parser_option_group(_("CLI Options"))
+ my_option_group.add_option(
+ '--file',
+ dest = "_file",
+ action = "store",
+ default = None,
+ metavar = "FILE",
+ help = _("List settings for file FILE")
+ )
+
+ my_option_group.add_option(
+ '--values',
+ dest = "values",
+ action = "store_true",
+ default = False,
+ help = _("Include values when listing settings.")
+ )
+
+def description():
+ return """List managed settings for file FILE."""
+
+def execute(*args, **kw):
+ if conf._file == None:
+ print >> sys.stderr, _("Unwilling to list all settings for all files. Specify a file path with --file.")
+ sys.exit(1)
+
+ _file = confmgmt.get_file(conf._file)
+
+ if _file == None:
+ print >> sys.stderr, _("No such file %s") %(conf._file)
+ sys.exit(1)
+
+ for setting in _file.settings:
+ if len(setting.roles) > 0:
+ print "- %s (Roles: %s)" % (setting.key, ', '.join([x.name for x in setting.roles]))
+ else:
+ print "- %s" % (setting.key)
+
+ if conf.values:
+ if not setting.value == None:
+ print "%-4s Value: %s" % ('', setting.value)
+ elif not setting.function == None:
+ print "%-4s Function: %s" % ('', setting.function)
diff --git a/pykolab/cli/conf/cmd_file_set_setting.py b/pykolab/cli/conf/cmd_file_set_setting.py
new file mode 100644
index 0000000..9bea1bf
--- /dev/null
+++ b/pykolab/cli/conf/cmd_file_set_setting.py
@@ -0,0 +1,125 @@
+# -*- coding: utf-8 -*-
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import sys
+import time
+
+import pykolab
+
+from pykolab import confmgmt
+from pykolab import constants
+from pykolab.cli import commands
+from pykolab.confmgmt.db import get_db
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.cli')
+conf = pykolab.getConf()
+
+def __init__():
+ commands.register('file_set_setting', execute, group='conf', description=description())
+
+def cli_options():
+ my_option_group = conf.add_cli_parser_option_group(_("CLI Options"))
+ my_option_group.add_option(
+ '--file',
+ dest = "_file",
+ action = "store",
+ default = None,
+ metavar = "FILE",
+ help = _("Add file FILE")
+ )
+
+ my_option_group.add_option(
+ '--role',
+ dest = "roles",
+ action = "append",
+ default = [],
+ metavar = "ROLE",
+ help = _("Exclusively associate the setting for file FILE with role ROLE. May be specified multiple times to associate the file setting with multiple roles.")
+ )
+
+ my_option_group.add_option(
+ '--key',
+ dest = "key",
+ action = "store",
+ default = None,
+ metavar = "KEY",
+ help = _("The key or 'name' for the setting.")
+ )
+
+ my_option_group.add_option(
+ '--value',
+ dest = "value",
+ action = "store",
+ default = None,
+ metavar = "VALUE",
+ help = _("Set to value VALUE.")
+ )
+
+ my_option_group.add_option(
+ '--function',
+ dest = "function",
+ action = "store",
+ default = None,
+ metavar = "FUNCTION",
+ help = _("Set to function FUNCTION.")
+ )
+
+def description():
+ return """Change the value or function for a managed setting with key KEY in file FILE."""
+
+def execute(*args, **kw):
+ if conf._file == None:
+ print >> sys.stderr, _("Must specify a file.")
+ sys.exit(1)
+
+ if conf.key == None:
+ print >> sys.stderr, _("Must specify a key.")
+ sys.exit(1)
+
+ if conf.value == None and conf.function == None:
+ print >> sys.stderr, _("Must specify a value or a function to get the values with.")
+ sys.exit(1)
+
+ if not conf.value == None and not conf.function == None:
+ print >> sys.stderr, _("Can only specify one of value or function.")
+ sys.exit(1)
+
+ _file = confmgmt.get_file(conf._file)
+
+ if _file == None:
+ print >> sys.stderr, _("File %s does not exist.") % (conf._file)
+ sys.exit(1)
+
+ if not conf.key in [x.key for x in _file.settings]:
+ print >> sys.stderr, _("Setting with key %s is not managed in file %s") % (conf.key, conf._file)
+ sys.exit(1)
+
+ setting = confmgmt.get_setting(conf.key, conf._file)
+
+ if setting == None:
+ print >> sys.stderr, _("Setting with key %s is not managed in file %s") % (conf.key, conf._file)
+ sys.exit(1)
+
+ if not conf.value == None:
+ setting.value = conf.value
+ elif not conf.function == None:
+ setting.function = conf.function
+
+ confmgmt.commit()
diff --git a/pykolab/cli/conf/cmd_init.py b/pykolab/cli/conf/cmd_init.py
new file mode 100644
index 0000000..ec6286d
--- /dev/null
+++ b/pykolab/cli/conf/cmd_init.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import sys
+import time
+
+import pykolab
+
+from pykolab import confmgmt
+from pykolab import utils
+from pykolab.cli import commands
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.cli')
+conf = pykolab.getConf()
+
+def __init__():
+ commands.register('init', execute, group='conf', description=description())
+
+def description():
+ return """Initialize configuration management."""
+
+def execute(*args, **kw):
+ for environment in [ "development", "testing", "production" ]:
+ confmgmt.add_environment(environment)
+
+ for role in [ "imap-server", "imap-server-frontend", "imap-server-mupdate", "imap-server-backend" ]:
+ confmgmt.add_role(role)
\ No newline at end of file
diff --git a/pykolab/cli/conf/cmd_list_environments.py b/pykolab/cli/conf/cmd_list_environments.py
new file mode 100644
index 0000000..92bee0f
--- /dev/null
+++ b/pykolab/cli/conf/cmd_list_environments.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import sys
+import time
+
+import pykolab
+
+from pykolab import confmgmt
+from pykolab import constants
+from pykolab.cli import commands
+from pykolab.confmgmt.db import get_db
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.cli')
+conf = pykolab.getConf()
+
+def __init__():
+ commands.register('list_environments', execute, group='conf', description=description())
+
+def description():
+ return """List environments."""
+
+def execute(*args, **kw):
+ environments = confmgmt.list_environments()
+
+ for environment in environments:
+ print "- %s" % (environment.name)
diff --git a/pykolab/cli/conf/cmd_list_files.py b/pykolab/cli/conf/cmd_list_files.py
new file mode 100644
index 0000000..9db5045
--- /dev/null
+++ b/pykolab/cli/conf/cmd_list_files.py
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import sys
+import time
+
+import pykolab
+
+from pykolab import confmgmt
+from pykolab import constants
+from pykolab.cli import commands
+from pykolab.confmgmt.db import get_db
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.cli')
+conf = pykolab.getConf()
+
+def __init__():
+ commands.register('list_files', execute, group='conf', description=description())
+
+def cli_options():
+ my_option_group = conf.add_cli_parser_option_group(_("CLI Options"))
+ my_option_group.add_option(
+ '--service',
+ dest = "service",
+ action = "store",
+ default = None,
+ metavar = "SERVICE",
+ help = _("List only files associated with service SERVICE.")
+ )
+
+def description():
+ return """List files (for service SERVICE)."""
+
+def execute(*args, **kw):
+ files = confmgmt.list_files()
+
+ if not conf.service == None:
+ service = confmgmt.get_service(conf.service)
+ if service == None:
+ print >> sys.stderr, _("No such service %s") % (conf.service)
+ sys.exit(1)
+
+ for _file in files:
+ if not conf.service == None:
+ if service.name in [x.name for x in _file.services]:
+ print "- %s" % (_file.path)
+ else:
+ print "- %s" % (_file.path)
diff --git a/pykolab/cli/conf/cmd_list_nodes.py b/pykolab/cli/conf/cmd_list_nodes.py
new file mode 100644
index 0000000..853553d
--- /dev/null
+++ b/pykolab/cli/conf/cmd_list_nodes.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import sys
+import time
+
+import pykolab
+
+from pykolab import confmgmt
+from pykolab import constants
+from pykolab.cli import commands
+from pykolab.confmgmt.db import get_db
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.cli')
+conf = pykolab.getConf()
+
+def __init__():
+ commands.register('list_nodes', execute, group='conf', description=description())
+
+def cli_options():
+ my_option_group = conf.add_cli_parser_option_group(_("CLI Options"))
+ my_option_group.add_option(
+ '--environment',
+ dest = "environment",
+ action = "store",
+ default = None,
+ metavar = "ENVIRONMENT",
+ help = _("List only nodes in environment ENVIRONMENT.")
+ )
+
+def description():
+ return """List nodes (in environment ENVIRONMENT)."""
+
+def execute(*args, **kw):
+ nodes = confmgmt.list_nodes()
+
+ if not conf.environment == None:
+ environment = confmgmt.get_environment(conf.environment)
+ if environment == None:
+ print >> sys.stderr, _("No such environment %s") % (conf.environment)
+ sys.exit(1)
+
+ for node in nodes:
+ if not conf.environment == None and node.environment == environment:
+ print "- %s" % (node.fqdn)
+ else:
+ print "- %s" % (node.fqdn)
diff --git a/pykolab/cli/conf/cmd_list_orphans.py b/pykolab/cli/conf/cmd_list_orphans.py
new file mode 100644
index 0000000..e312318
--- /dev/null
+++ b/pykolab/cli/conf/cmd_list_orphans.py
@@ -0,0 +1,100 @@
+# -*- coding: utf-8 -*-
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import sys
+import time
+
+import pykolab
+
+from pykolab import confmgmt
+from pykolab import constants
+from pykolab.cli import commands
+from pykolab.confmgmt.db import get_db
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.cli')
+conf = pykolab.getConf()
+
+def __init__():
+ commands.register('list_orphans', execute, group='conf', description=description())
+
+def cli_options():
+ my_option_group = conf.add_cli_parser_option_group(_("CLI Options"))
+ my_option_group.add_option(
+ '--purge',
+ dest = "purge",
+ action = "store_true",
+ default = False,
+ help = _("Purge orphaned objects.")
+ )
+
+ my_option_group.add_option(
+ '--files',
+ dest = "files",
+ action = "store_true",
+ default = False,
+ help = _("List orphaned files.")
+ )
+
+ my_option_group.add_option(
+ '--roles',
+ dest = "roles",
+ action = "store_true",
+ default = False,
+ help = _("List orphaned roles.")
+ )
+
+ my_option_group.add_option(
+ '--services',
+ dest = "services",
+ action = "store_true",
+ default = False,
+ help = _("List orphaned services.")
+ )
+
+def description():
+ return """List files, services, settings, roles, etc. that are not associated with anything else."""
+
+def execute(*args, **kw):
+ if conf.files:
+ files = confmgmt.list_files()
+
+ for _file in files:
+ if len(_file.services) < 1:
+ print _("File %s not associated with any services.") % (_file.path)
+
+ if len(_file.settings) < 1:
+ print _("File %s has no settings associated with it.") % (_file.path)
+
+ if conf.roles:
+ roles = confmgmt.list_roles()
+
+ for role in roles:
+ if len(role.nodes) < 1:
+ print _("Role %s not associated with any nodes.") % (role.name)
+
+ if len(role.services) < 1:
+ print _("Role %s has no services associated with it.") % (role.name)
+
+ if conf.services:
+ services = confmgmt.list_services()
+
+ for service in services:
+ if len(service.roles) < 1:
+ print _("Service %s not associated with any roles.") % (service.name)
diff --git a/pykolab/cli/conf/cmd_list_roles.py b/pykolab/cli/conf/cmd_list_roles.py
new file mode 100644
index 0000000..e59ca85
--- /dev/null
+++ b/pykolab/cli/conf/cmd_list_roles.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import sys
+import time
+
+import pykolab
+
+from pykolab import confmgmt
+from pykolab import constants
+from pykolab.cli import commands
+from pykolab.confmgmt.db import get_db
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.cli')
+conf = pykolab.getConf()
+
+def __init__():
+ commands.register('list_roles', execute, group='conf', description=description())
+
+def description():
+ return """List roles."""
+
+def execute(*args, **kw):
+ roles = confmgmt.list_roles()
+
+ for role in roles:
+ print "- %s" % (role.name)
diff --git a/pykolab/cli/conf/cmd_node_add_role.py b/pykolab/cli/conf/cmd_node_add_role.py
new file mode 100644
index 0000000..1f73109
--- /dev/null
+++ b/pykolab/cli/conf/cmd_node_add_role.py
@@ -0,0 +1,76 @@
+# -*- coding: utf-8 -*-
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import sys
+import time
+
+import pykolab
+
+from pykolab import confmgmt
+from pykolab import constants
+from pykolab.cli import commands
+from pykolab.confmgmt.db import get_db
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.cli')
+conf = pykolab.getConf()
+
+def __init__():
+ commands.register('node_add_role', execute, group='conf', description=description())
+
+def cli_options():
+ my_option_group = conf.add_cli_parser_option_group(_("CLI Options"))
+ my_option_group.add_option(
+ '--node',
+ dest = "node",
+ action = "store",
+ default = constants.fqdn,
+ metavar = "FQDN",
+ help = _("Add role ROLE to node FQDN")
+ )
+
+ my_option_group.add_option(
+ '--role',
+ dest = "role",
+ action = "store",
+ default = None,
+ metavar = "ROLE",
+ help = _("Add role ROLE")
+ )
+
+def description():
+ return """Add role to node."""
+
+def execute(*args, **kw):
+ node = confmgmt.get_node(conf.node)
+ role = confmgmt.get_role(conf.role)
+
+ if node == None:
+ print >> sys.stderr, _("No such node %s") % (conf.node)
+ sys.exit(1)
+
+ if role == None:
+ print >> sys.stderr, _("No such role %s") % (conf.role)
+ sys.exit(1)
+
+ if role in node.roles:
+ print >> sys.stderr, _("Node %s already has role %s") % (conf.node, conf.role)
+ sys.exit(1)
+
+ confmgmt.add_node_role(node, role)
diff --git a/pykolab/cli/conf/cmd_node_list_files.py b/pykolab/cli/conf/cmd_node_list_files.py
new file mode 100644
index 0000000..00b4e39
--- /dev/null
+++ b/pykolab/cli/conf/cmd_node_list_files.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import sys
+import time
+
+import pykolab
+
+from pykolab import confmgmt
+from pykolab import constants
+from pykolab.cli import commands
+from pykolab.confmgmt.db import get_db
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.cli')
+conf = pykolab.getConf()
+
+def __init__():
+ commands.register('node_list_files', execute, group='conf', description=description())
+
+def cli_options():
+ my_option_group = conf.add_cli_parser_option_group(_("CLI Options"))
+ my_option_group.add_option(
+ '--node',
+ dest = "node",
+ action = "store",
+ default = constants.fqdn,
+ metavar = "FQDN",
+ help = _("List services (for node FQDN)")
+ )
+
+def description():
+ return """List files with managed settings applicable to node."""
+
+def execute(*args, **kw):
+ node = confmgmt.get_node(conf.node)
+
+ if node == None:
+ print >> sys.stderr, _("No such node %s") %(conf.node)
+ sys.exit(1)
+
+ files = confmgmt.get_node_files(conf.node)
+
+ for _file in files:
+ if _file.tech == "augeas":
+ print "- %s" % (_file.path)
+ else:
+ print "- %s (%s)" % (_file.path, _file.tech)
diff --git a/pykolab/cli/conf/cmd_node_list_roles.py b/pykolab/cli/conf/cmd_node_list_roles.py
new file mode 100644
index 0000000..075e0fd
--- /dev/null
+++ b/pykolab/cli/conf/cmd_node_list_roles.py
@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import sys
+import time
+
+import pykolab
+
+from pykolab import confmgmt
+from pykolab import constants
+from pykolab.cli import commands
+from pykolab.confmgmt.db import get_db
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.cli')
+conf = pykolab.getConf()
+
+def __init__():
+ commands.register('node_list_roles', execute, group='conf', description=description(), aliases=['list_node_roles'])
+
+def cli_options():
+ my_option_group = conf.add_cli_parser_option_group(_("CLI Options"))
+ my_option_group.add_option(
+ '--node',
+ dest = "node",
+ action = "store",
+ default = constants.fqdn,
+ metavar = "FQDN",
+ help = _("List roles (for node FQDN)")
+ )
+
+def description():
+ return """List roles for node."""
+
+def execute(*args, **kw):
+ node = confmgmt.get_node(conf.node)
+
+ if node == None:
+ print >> sys.stderr, _("No such node %s") %(conf.node)
+ sys.exit(1)
+
+ for role in node.roles:
+ print "- %s" % (role.name)
diff --git a/pykolab/cli/conf/cmd_node_list_services.py b/pykolab/cli/conf/cmd_node_list_services.py
new file mode 100644
index 0000000..e3491c8
--- /dev/null
+++ b/pykolab/cli/conf/cmd_node_list_services.py
@@ -0,0 +1,60 @@
+# -*- coding: utf-8 -*-
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import sys
+import time
+
+import pykolab
+
+from pykolab import confmgmt
+from pykolab import constants
+from pykolab.cli import commands
+from pykolab.confmgmt.db import get_db
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.cli')
+conf = pykolab.getConf()
+
+def __init__():
+ commands.register('node_list_services', execute, group='conf', description=description())
+
+def cli_options():
+ my_option_group = conf.add_cli_parser_option_group(_("CLI Options"))
+ my_option_group.add_option(
+ '--node',
+ dest = "node",
+ action = "store",
+ default = constants.fqdn,
+ metavar = "FQDN",
+ help = _("List services (for node FQDN)")
+ )
+
+def description():
+ return """List services for node."""
+
+def execute(*args, **kw):
+ node = confmgmt.get_node(conf.node)
+
+ if node == None:
+ print >> sys.stderr, _("No such node %s") %(conf.node)
+ sys.exit(1)
+
+ for role in node.roles:
+ for service in role.services:
+ print "- %s" % (service.name)
diff --git a/pykolab/cli/conf/cmd_node_list_settings.py b/pykolab/cli/conf/cmd_node_list_settings.py
new file mode 100644
index 0000000..ca336d6
--- /dev/null
+++ b/pykolab/cli/conf/cmd_node_list_settings.py
@@ -0,0 +1,82 @@
+# -*- coding: utf-8 -*-
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import sys
+import time
+
+import pykolab
+
+from pykolab import confmgmt
+from pykolab import constants
+from pykolab.cli import commands
+from pykolab.confmgmt.db import get_db
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.cli')
+conf = pykolab.getConf()
+
+def __init__():
+ commands.register('node_list_settings', execute, group='conf', description=description())
+
+def cli_options():
+ my_option_group = conf.add_cli_parser_option_group(_("CLI Options"))
+ my_option_group.add_option(
+ '--node',
+ dest = "node",
+ action = "store",
+ default = constants.fqdn,
+ metavar = "FQDN",
+ help = _("List settings for node FQDN")
+ )
+
+ my_option_group.add_option(
+ '--file',
+ dest = "_file",
+ action = "store",
+ default = None,
+ metavar = "FILE",
+ help = _("List settings for file FILE")
+ )
+
+def description():
+ return """List managed settings (for file FILE) applicable to node."""
+
+def execute(*args, **kw):
+ node = confmgmt.get_node(conf.node)
+
+ if node == None:
+ print >> sys.stderr, _("No such node %s") %(conf.node)
+ sys.exit(1)
+
+ files = confmgmt.get_node_files(conf.node)
+
+ for _file in files:
+ print "File %s" % (_file.path)
+ if conf._file == None or conf._file == _file.path:
+ for setting in _file.settings:
+ if len(setting.roles) > 0:
+ is_my_role_too = False
+ for _role in setting.roles:
+ if _role in node.roles:
+ is_my_role_too = True
+
+ if not is_my_role_too:
+ continue
+
+ print "%-3s %s" % ('', setting.key)
diff --git a/pykolab/cli/conf/cmd_node_remove_role.py b/pykolab/cli/conf/cmd_node_remove_role.py
new file mode 100644
index 0000000..58aa605
--- /dev/null
+++ b/pykolab/cli/conf/cmd_node_remove_role.py
@@ -0,0 +1,72 @@
+# -*- coding: utf-8 -*-
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import sys
+import time
+
+import pykolab
+
+from pykolab import confmgmt
+from pykolab import constants
+from pykolab.cli import commands
+from pykolab.confmgmt.db import get_db
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.cli')
+conf = pykolab.getConf()
+
+def __init__():
+ commands.register('node_remove_role', execute, group='conf', description=description())
+
+def cli_options():
+ my_option_group = conf.add_cli_parser_option_group(_("CLI Options"))
+ my_option_group.add_option(
+ '--node',
+ dest = "node",
+ action = "store",
+ default = constants.fqdn,
+ metavar = "FQDN",
+ help = _("Remove role ROLE from node FQDN")
+ )
+
+ my_option_group.add_option(
+ '--role',
+ dest = "role",
+ action = "store",
+ default = None,
+ metavar = "ROLE",
+ help = _("Remove role ROLE")
+ )
+
+def description():
+ return """Remove role from node."""
+
+def execute(*args, **kw):
+ node = confmgmt.get_node(conf.node)
+ role = confmgmt.get_role(conf.role)
+
+ if node == None:
+ print >> sys.stderr, _("No such node %s") %(conf.node)
+ sys.exit(1)
+
+ if role == None:
+ print >> sys.stderr, _("No such role %s") %(conf.role)
+ sys.exit(1)
+
+ confmgmt.remove_node_role(node, role)
diff --git a/pykolab/cli/conf/cmd_remove_environment.py b/pykolab/cli/conf/cmd_remove_environment.py
new file mode 100644
index 0000000..ba54d0d
--- /dev/null
+++ b/pykolab/cli/conf/cmd_remove_environment.py
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import sys
+import time
+
+import pykolab
+
+from pykolab import confmgmt
+from pykolab import constants
+from pykolab.cli import commands
+from pykolab.confmgmt.db import get_db
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.cli')
+conf = pykolab.getConf()
+
+def __init__():
+ commands.register('remove_environment', execute, group='conf', description=description())
+
+def cli_options():
+ my_option_group = conf.add_cli_parser_option_group(_("CLI Options"))
+ my_option_group.add_option(
+ '--environment',
+ dest = "environment",
+ action = "store",
+ default = None,
+ metavar = "ENVIRONMENT",
+ help = _("Remove environment ENVIRONMENT.")
+ )
+
+def description():
+ return """Remove an environment."""
+
+def execute(*args, **kw):
+ if conf.environment == None:
+ try:
+ conf.environment = conf.cli_args.pop(0)
+ except IndexError, errmsg:
+ print >> sys.stderr, _("Must specify an environment name to delete an environment.")
+ sys.exit(1)
+
+ environment = confmgmt.get_environment(conf.environment)
+
+ if environment == None:
+ print >> sys.stderr, _("No environment with name %s exists.") % (conf.environment)
+ sys.exit(1)
+
+ confmgmt.remove_environment(environment)
\ No newline at end of file
diff --git a/pykolab/cli/conf/cmd_remove_role.py b/pykolab/cli/conf/cmd_remove_role.py
new file mode 100644
index 0000000..2ac9637
--- /dev/null
+++ b/pykolab/cli/conf/cmd_remove_role.py
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import sys
+import time
+
+import pykolab
+
+from pykolab import confmgmt
+from pykolab import constants
+from pykolab.cli import commands
+from pykolab.confmgmt.db import get_db
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.cli')
+conf = pykolab.getConf()
+
+def __init__():
+ commands.register('remove_role', execute, group='conf', description=description())
+
+def cli_options():
+ my_option_group = conf.add_cli_parser_option_group(_("CLI Options"))
+ my_option_group.add_option(
+ '--role',
+ dest = "role",
+ action = "store",
+ default = None,
+ metavar = "ROLE",
+ help = _("Remove role ROLE.")
+ )
+
+def description():
+ return """Remove a role."""
+
+def execute(*args, **kw):
+ if conf.role == None:
+ try:
+ conf.role = conf.cli_args.pop(0)
+ except IndexError, errmsg:
+ print >> sys.stderr, _("Must specify a role name to delete a role.")
+ sys.exit(1)
+
+ role = confmgmt.get_role(conf.role)
+
+ if role == None:
+ print >> sys.stderr, _("No role with name %s exists.") % (conf.role)
+ sys.exit(1)
+
+ confmgmt.remove_role(role)
diff --git a/pykolab/cli/conf/cmd_role_add_service.py b/pykolab/cli/conf/cmd_role_add_service.py
new file mode 100644
index 0000000..30db5be
--- /dev/null
+++ b/pykolab/cli/conf/cmd_role_add_service.py
@@ -0,0 +1,72 @@
+# -*- coding: utf-8 -*-
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import sys
+import time
+
+import pykolab
+
+from pykolab import confmgmt
+from pykolab import constants
+from pykolab.cli import commands
+from pykolab.confmgmt.db import get_db
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.cli')
+conf = pykolab.getConf()
+
+def __init__():
+ commands.register('role_add_service', execute, group='conf', description=description())
+
+def cli_options():
+ my_option_group = conf.add_cli_parser_option_group(_("CLI Options"))
+ my_option_group.add_option(
+ '--role',
+ dest = "role",
+ action = "store",
+ default = None,
+ metavar = "ROLE",
+ help = _("Use role ROLE")
+ )
+
+ my_option_group.add_option(
+ '--service',
+ dest = "service",
+ action = "store",
+ default = None,
+ metavar = "SERVICE",
+ help = _("Use service SERVICE")
+ )
+
+def description():
+ return """Associate a service with a role."""
+
+def execute(*args, **kw):
+ role = confmgmt.get_role(conf.role)
+ service = confmgmt.get_service(conf.service)
+
+ if role == None:
+ print >> sys.stderr, _("No such role %s") % (conf.role)
+ sys.exit(1)
+
+ if service == None:
+ print >> sys.stderr, _("No such service %s") % (conf.service)
+ sys.exit(1)
+
+ confmgmt.add_role_service(role, service)
commit b5f1f9fc37a6a60e159151ff5e5e81b26bfaf761
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date: Fri Dec 14 10:57:17 2012 +0000
Add confmgmt module, model and database
diff --git a/pykolab/confmgmt/__init__.py b/pykolab/confmgmt/__init__.py
new file mode 100644
index 0000000..8958ead
--- /dev/null
+++ b/pykolab/confmgmt/__init__.py
@@ -0,0 +1,333 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import pykolab
+
+log = pykolab.getLogger('pykolab.confmgmt')
+
+from pykolab.confmgmt.db import get_db
+
+from pykolab.confmgmt.model import Environment
+from pykolab.confmgmt.model import File
+from pykolab.confmgmt.model import Node
+from pykolab.confmgmt.model import Package
+from pykolab.confmgmt.model import Role
+from pykolab.confmgmt.model import Service
+from pykolab.confmgmt.model import Setting
+
+def add_environment(name=None):
+ db = get_db()
+
+ if not name == None:
+ environment = db.query(Environment).filter_by(name=name).first()
+ if not environment == None:
+ return environment
+
+ environments = db.query(Environment).all()
+
+ if len(environments) == 0 and name == None:
+ return add_environment('development')
+ else:
+ db.add(Environment(name=name))
+ db.commit()
+
+ environment = db.query(Environment).filter_by(name=name).first()
+
+ return environment
+
+def add_file(file_path, tech=None):
+ log.debug("Adding file %r" % (file_path))
+ db = get_db()
+
+ _file = db.query(File).filter_by(path=file_path).first()
+
+ if _file == None:
+ db.add(File(path=file_path, tech=tech))
+ db.commit()
+
+ _file = db.query(File).filter_by(path=file_path).first()
+
+ return _file
+
+def add_file_setting(_file, setting):
+ db = get_db()
+ _file.settings.append(setting)
+ db.commit()
+
+def add_node(node_fqdn):
+ log.debug("Adding node %r" % (node_fqdn))
+ db = get_db()
+ node = db.query(Node).filter_by(fqdn=node_fqdn).first()
+
+ if node == None:
+ db.add(Node(fqdn=node_fqdn))
+ db.commit()
+
+ node = db.query(Node).filter_by(fqdn=node_fqdn).first()
+
+ node.environment = add_environment()
+
+ db.commit()
+
+ return node
+
+def add_node_role(node, role):
+ log.debug("Adding node %r role %r" % (node.fqdn, role.name))
+ db = get_db()
+ node.roles.append(role)
+ db.commit()
+
+def add_package():
+ pass
+
+def add_package_file():
+ pass
+
+def add_package_service():
+ pass
+
+def add_role(role):
+ log.debug("Adding role %r" % (role))
+ db = get_db()
+
+ _role = db.query(Role).filter_by(name=role).first()
+ if _role == None:
+ db.add(Role(name=role))
+ db.commit()
+
+ _role = db.query(Role).filter_by(name=role).first()
+
+ return _role
+
+def add_role_service(_role,_service):
+ log.debug("Adding role %r service %r" % (_role.name, _service.name))
+ db = get_db()
+
+ _role.services.append(_service)
+
+ db.commit()
+
+def add_role_setting():
+ pass
+
+def add_service(service):
+ db = get_db()
+
+ _service = db.query(Service).filter_by(name=service).first()
+
+ if _service == None:
+ db.add(Service(name=service))
+ db.commit()
+
+ _service = db.query(Service).filter_by(name=service).first()
+
+ return _service
+
+def add_service_file(service, _file):
+ db = get_db()
+ service.files.append(_file)
+ db.commit()
+
+def add_setting(key, value, function):
+ db = get_db()
+
+ _setting = db.query(Setting).filter_by(key=key, value=value, function=function).first()
+
+ if _setting == None:
+ db.add(Setting(key=key, value=value, function=function))
+ db.commit()
+
+ _setting = db.query(Setting).filter_by(key=key, value=value, function=function).first()
+
+ return _setting
+
+def _add_setting(file_path, key, value=None, function=None, service_name=None, role_name=None, tech=None):
+ if not service_name == None:
+ log.debug(_("Searching for service with name %s") % (service_name), level=8)
+ service = add_service(service_name)
+ if not service == None:
+ log.debug(_("Found service %s") % (service_name), level=8)
+ else:
+ service = None
+
+ if not role_name == None:
+ log.debug(_("Searching for role with name %s") % (role_name), level=8)
+ role = add_role(role_name)
+ if not role == None:
+ log.debug(_("Found role %s") % (role_name), level=8)
+ else:
+ role = None
+
+ log.debug(_("Searching for file with path %s") % (file_path), level=8)
+ _file = add_file(file_path, tech)
+
+ if not service_name == None:
+ log.debug(_("Adding file with path %s to service with name %s") % (file_path, service_name), level=8)
+ add_service_file(service, _file)
+
+ log.debug(_("Adding setting with key %s (%r, %r)") % (key, value, function), level=8)
+ setting = add_setting(key=key, value=value, function=function)
+
+ log.debug(_("Adding setting %s to file with path %s") % (key, file_path), level=8)
+ add_file_setting(_file, setting)
+
+ if not role == None:
+ log.debug(_("Adding role with name %s to setting with key %s") %(role_name, key), level=8)
+ setting.roles.append(role)
+
+def commit():
+ db = get_db()
+ db.commit()
+
+def get_environment(name):
+ """
+ Return the environment record for the environment with name 'name'.
+ """
+ db = get_db()
+ environment = db.query(Environment).filter_by(name=name).first()
+ return environment
+
+def get_file(path):
+ """
+ Return a file record for the file with path 'path'.
+ """
+ db = get_db()
+ _file = db.query(File).filter_by(path=path).first()
+ return _file
+
+def get_node(fqdn):
+ """
+ Return a node record for the node with FQDN 'fqdn'.
+ """
+ db = get_db()
+ node = db.query(Node).filter_by(fqdn=fqdn).first()
+ return node
+
+def get_node_files(fqdn):
+ """
+ Get a list of file records that are relevant for the node with FQDN 'fqdn'.
+ """
+ files = []
+
+ node = get_node(fqdn)
+
+ if node == None:
+ return files
+
+ for role in node.roles:
+ for service in role.services:
+ for _file in service.files:
+ _settings = []
+
+ for setting in _file.settings:
+ if len(setting.roles) > 0:
+ if (len([needle.name for needle in setting.roles if needle.name in [haystack.name for haystack in node.roles]]) > 0):
+ _settings.append(setting.key)
+ else:
+ _settings.append(setting.key)
+
+ if len(_settings) > 0:
+ files.append(_file)
+
+ return files
+
+def get_role(name):
+ """
+ Return a role record for the role with name 'name'.
+ """
+ db = get_db()
+ role = db.query(Role).filter_by(name=name).first()
+ return role
+
+def get_service(name):
+ """
+ Return the service record for the service with name 'name'.
+ """
+ db = get_db()
+ service = db.query(Service).filter_by(name=name).first()
+ return service
+
+def get_setting(key, path, roles=[]):
+ """
+ Return the setting record for setting 'key' in file 'file_path'.
+ """
+ db = get_db()
+ _file = db.query(File).filter_by(path=path).first()
+ setting = db.query(Setting).filter_by(key=key).filter(Setting.files.contains(_file)).first()
+ return setting
+
+def list_environments():
+ """
+ List environments.
+ """
+ db = get_db()
+ environments = db.query(Environment).all()
+ return environments
+
+def list_files():
+ """
+ List files.
+ """
+ db = get_db()
+ files = db.query(File).all()
+ return files
+
+def list_nodes():
+ """
+ List nodes.
+ """
+ db = get_db()
+ nodes = db.query(Node).all()
+ return nodes
+
+def list_roles():
+ """
+ List roles.
+ """
+ db = get_db()
+ roles = db.query(Role).all()
+ return roles
+
+def list_services():
+ """
+ List services.
+ """
+ db = get_db()
+ services = db.query(Service).all()
+ return services
+
+def remove_environment(environment):
+ db = get_db()
+
+ db.delete(environment)
+ db.commit()
+
+def remove_node_role(node, role):
+ log.debug("Removing node %r role %r" % (node.fqdn, role.name))
+ db = get_db()
+ node.roles.pop(node.roles.index(role))
+ db.commit()
+
+def remove_role(role):
+ db = get_db()
+
+ db.delete(role)
+ db.commit()
+
diff --git a/pykolab/confmgmt/db.py b/pykolab/confmgmt/db.py
new file mode 100644
index 0000000..e42bcae
--- /dev/null
+++ b/pykolab/confmgmt/db.py
@@ -0,0 +1,140 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+from sqlalchemy import create_engine
+
+try:
+ from sqlalchemy.orm import sessionmaker
+except:
+ from sqlalchemy.orm import create_session
+
+from model import Base
+from model import Environment
+from model import File
+from model import Node
+from model import Package
+from model import Role
+from model import Service
+from model import Setting
+#from confmgmt.model import Task
+
+import pykolab
+from pykolab.auth import Auth
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.confmgmt')
+conf = pykolab.getConf()
+
+db = None
+
+def get_db():
+ global db
+
+ if db == None:
+ return init_db()
+
+ return db
+
+def init_db():
+ """
+ Returns a SQLAlchemy Session() instance.
+ """
+ global db
+
+ db_uri = "mysql://root:Welcome2KolabSystems@localhost/kolab"
+
+ if not db_uri == None:
+ echo = conf.debuglevel > 8
+ engine = create_engine(db_uri, echo=echo)
+
+ if conf.debuglevel > 8:
+ log.info(_("Dropping all tables..."))
+ Base.metadata.drop_all(engine)
+
+ log.info(_("Creating the necessary tables..."))
+ Base.metadata.create_all(engine)
+
+ Session = sessionmaker(bind=engine)
+ db = Session()
+
+ if db == None:
+ log.error(_("No database available"))
+
+ return db
+
+def ldap_server_hostname_from_uri():
+ ldap_uri = conf.get('ldap', 'ldap_uri')
+ hostname = None
+ port = None
+
+ from urlparse import urlparse
+
+ result = urlparse(ldap_uri)
+
+ if hasattr(result, 'hostname'):
+ hostname = result.hostname
+ else:
+ scheme = ldap_uri.split(':')[0]
+ (hostname, port) = ldap_uri.split('/')[2].split(':')
+
+ return hostname
+
+def list_domains():
+ domains = []
+ print "Listing domains"
+ auth = Auth()
+ auth.connect()
+ _domains = auth.list_domains()
+ print "Domains:", _domains
+ for domain,domain_aliases in _domains:
+ domains.append(domain)
+ domains.extend(domain_aliases)
+
+ return domains
+
+def list_nodes_by_role(role):
+ print "Executing list_nodes_by_role() for role", role
+ role = db.query(Role).filter_by(name=role).first()
+
+ nodes = []
+
+ for node in role.nodes:
+ if not node.fqdn in nodes:
+ nodes.append(node.fqdn)
+
+ return nodes
+
+def list_users_by_role(role, result_attr):
+ print "Executing list_users_by_role() for role", role
+ auth = Auth()
+ auth.connect()
+ user_dns = auth.search_entry_by_attribute('nsroledn', 'cn=%s,%s' % (role,conf.get('ldap','base_dn')))
+
+ print user_dns
+
+ user_login_names = []
+
+ for user_dn in user_dns:
+ user_login_names.append(auth.get_user_attribute(None, {'dn': user_dn}, result_attr))
+
+ print "User login names:", user_login_names
+
+ return user_login_names
+
diff --git a/pykolab/confmgmt/model.py b/pykolab/confmgmt/model.py
new file mode 100644
index 0000000..3652d8d
--- /dev/null
+++ b/pykolab/confmgmt/model.py
@@ -0,0 +1,545 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright 2010-2012 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 3 or, at your option, any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import datetime
+
+import sqlalchemy
+
+from sqlalchemy import Column
+from sqlalchemy import MetaData
+from sqlalchemy import Table
+
+from sqlalchemy import DateTime
+from sqlalchemy import ForeignKey
+from sqlalchemy import Integer
+from sqlalchemy import String
+from sqlalchemy import Text
+
+from sqlalchemy.interfaces import PoolListener
+
+from sqlalchemy.orm import mapper
+
+try:
+ from sqlalchemy.orm import relationship
+except:
+ from sqlalchemy.orm import relation as relationship
+
+from sqlalchemy.ext.declarative import declarative_base
+
+from sqlalchemy.schema import Index
+from sqlalchemy.schema import UniqueConstraint
+
+import pykolab
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.confmgmt')
+conf = pykolab.getConf()
+
+Base = declarative_base()
+
+# A single file has multiple settings.
+file_settings_table = Table(
+ 'file_settings', Base.metadata,
+ Column('file_id', Integer, ForeignKey('file.id')),
+ Column('setting_id', Integer, ForeignKey('setting.id'))
+ )
+
+# A node has multiple roles.
+node_roles_table = Table(
+ 'node_roles', Base.metadata,
+ Column('node_id', Integer, ForeignKey('node.id')),
+ Column('role_id', Integer, ForeignKey('role.id'))
+ )
+
+# A package ships multiple files, and each file belongs to one package (at the
+# most).
+package_files_table = Table(
+ 'package_files', Base.metadata,
+ Column('package_id', Integer, ForeignKey('package.id')),
+ Column('file_id', Integer, ForeignKey('file.id'))
+ )
+
+package_services_table = Table(
+ 'package_services', Base.metadata,
+ Column('package_id', Integer, ForeignKey('package.id')),
+ Column('service_id', Integer, ForeignKey('service.id'))
+ )
+
+# Each role implies running one or more services.
+role_services_table = Table(
+ 'role_services', Base.metadata,
+ Column('role_id', Integer, ForeignKey('role.id')),
+ Column('service_id', Integer, ForeignKey('service.id'))
+ )
+
+role_settings_table = Table(
+ 'role_settings', Base.metadata,
+ Column('role_id', Integer, ForeignKey('role.id')),
+ Column('setting_id', Integer, ForeignKey('setting.id'))
+ )
+
+service_files_table = Table(
+ 'service_files', Base.metadata,
+ Column('service_id', Integer, ForeignKey('service.id')),
+ Column('file_id', Integer, ForeignKey('file.id'))
+ )
+
+class Environment(Base):
+ __tablename__ = 'environment'
+
+ id = Column(Integer, primary_key=True)
+ # TODO: unique constraint
+ name = Column(String(16), nullable=False)
+ description = Column(String(128), nullable=True)
+
+ # One to many
+ nodes = relationship(
+ 'Node',
+ backref='environment'
+ )
+
+class File(Base):
+ __tablename__ = 'file'
+
+ id = Column(Integer, primary_key=True)
+ path = Column(Text, nullable=False)
+ tech = Column(String(7), nullable=False, default='augeas')
+
+ package = relationship(
+ 'Package',
+ secondary=package_files_table
+ )
+
+ services = relationship(
+ 'Service',
+ secondary=service_files_table
+ )
+
+ settings = relationship(
+ 'Setting',
+ secondary=file_settings_table
+ )
+
+class Node(Base):
+ __tablename__ = 'node'
+
+ id = Column(Integer, primary_key=True)
+ fqdn = Column(String(128), nullable=False)
+
+ # One node can only belong to one environment at a time
+ environment_id = Column(Integer, ForeignKey('environment.id'))
+
+ roles = relationship(
+ 'Role',
+ secondary=node_roles_table
+ )
+
+class Package(Base):
+ __tablename__ = 'package'
+
+ id = Column(Integer, primary_key=True)
+ name = Column(String(256), nullable=False)
+
+ files = relationship(
+ 'File',
+ secondary=package_files_table
+ )
+
+ services = relationship(
+ 'Service',
+ secondary=package_services_table
+ )
+
+class Role(Base):
+ __tablename__ = 'role'
+
+ id = Column(Integer, primary_key=True)
+ name = Column(String(128), nullable=False)
+
+ nodes = relationship(
+ 'Node',
+ secondary=node_roles_table
+ )
+
+ services = relationship(
+ 'Service',
+ secondary=role_services_table
+ )
+
+ settings = relationship(
+ 'Setting',
+ secondary=role_settings_table
+ )
+
+class Service(Base):
+ __tablename__ = 'service'
+
+ id = Column(Integer, primary_key=True)
+ name = Column(String(128), nullable=False)
+
+ files = relationship(
+ 'File',
+ secondary=service_files_table
+ )
+
+ package = relationship(
+ 'Package',
+ secondary=package_services_table
+ )
+
+ roles = relationship(
+ 'Role',
+ secondary=role_services_table
+ )
+
+class Setting(Base):
+ __tablename__ = 'setting'
+
+ id = Column(Integer, primary_key=True)
+ key = Column(String(128), nullable=False)
+
+ environment_id = Column(Integer, ForeignKey('environment.id'))
+
+ value = Column(Text, nullable=True)
+ function = Column(Text, nullable=True)
+
+ files = relationship(
+ 'File',
+ secondary=file_settings_table
+ )
+
+ roles = relationship(
+ 'Role',
+ secondary=role_settings_table
+ )
+
+def list_nodes_by_role(role):
+ role = db.query(Role).filter_by(name=role).first()
+
+ nodes = []
+
+ for node in role.nodes:
+ if not node.fqdn in nodes:
+ nodes.append(node.fqdn)
+
+ return nodes
+
+def list_users_by_role(role, result_attr):
+ auth = pykolab.auth
+ auth.connect()
+ user_dns = auth.search_users('nsrole', 'cn=%s,dc=klab,dc=cc' % (role), base_dn="dc=klab,dc=cc")
+
+ user_login_names = []
+
+ for user_dn in user_dns:
+ user_login_names.append(auth.get_user_attribute(None, {'dn': user_dn}, result_attr))
+
+ return user_login_names
+
+if __name__ == "__main__":
+ db = init_db()
+
+ if conf.debuglevel > 8:
+ environment = db.query(Environment).all()
+
+ if len(environment) == 0:
+ db.add(Environment(name='development'))
+ db.commit()
+
+ environment = db.query(Environment).filter_by(name='development').first()
+
+ # Add a series of nodes.
+ for node_fqdn in PRETEND_TO_HAVE_NODES:
+ node = db.query(Node).filter_by(fqdn=node_fqdn).first()
+
+ if node == None:
+ db.add(Node(fqdn=node_fqdn))
+ db.commit()
+
+ node = db.query(Node).filter_by(fqdn=node_fqdn).first()
+
+ node.environment = environment
+
+ db.commit()
+
+ roles = {
+ 'mta-internal': {
+ 'services': [
+ 'postfix'
+ ]
+ },
+ 'mta-external': {
+ 'services': [
+ 'postfix'
+ ]
+ },
+ 'mta-backend': {
+ 'services': [
+ 'postfix'
+ ]
+ },
+ 'mta-content-filter': {
+ 'services': [
+ 'postfix'
+ ]
+ },
+ 'content-filter': {
+ 'services': [
+ 'postfix'
+ ]
+ },
+ 'imap-server-backend': {
+ 'services': [
+ 'postfix',
+ 'cyrus-imapd'
+ ]
+ },
+ 'imap-server-frontend': {
+ 'services': [
+ 'postfix',
+ 'cyrus-imapd'
+ ]
+ }
+ }
+
+ for role in roles.keys():
+ _role = db.query(Role).filter_by(name=role).first()
+ if _role == None:
+ db.add(Role(name=role))
+ db.commit()
+
+ _role = db.query(Role).filter_by(name=role).first()
+
+ if isinstance(roles[role], dict):
+ if roles[role].has_key('services'):
+ for service in roles[role]['services']:
+ _service = db.query(Service).filter_by(name=service).first()
+
+ if _service == None:
+ db.add(Service(name=service))
+ db.commit()
+
+ _service = db.query(Service).filter_by(name=service).first()
+
+ _role.services.append(_service)
+
+ db.commit()
+
+ for node_fqdn in PRETEND_TO_HAVE_NODES:
+ node = db.query(Node).filter_by(fqdn=node_fqdn).first()
+ if node.fqdn.startswith(role):
+ node.roles.append(_role)
+ db.commit()
+
+ db.commit()
+
+ # Add /etc/imapd.conf for cyrus-imapd service
+ service = db.query(Service).filter_by(name='cyrus-imapd').first()
+ file = db.query(File).filter_by(path='/etc/imapd.conf').first()
+ if file == None:
+ db.add(File(path='/etc/imapd.conf'))
+ file = db.query(File).filter_by(path='/etc/imapd.conf').first()
+ service.files.append(file)
+ db.commit()
+
+ # Add /etc/cyrus.conf for cyrus-imapd service
+ service = db.query(Service).filter_by(name='cyrus-imapd').first()
+ file = db.query(File).filter_by(path='/etc/cyrus.conf').first()
+ if file == None:
+ db.add(File(path='/etc/cyrus.conf'))
+ file = db.query(File).filter_by(path='/etc/cyrus.conf').first()
+ service.files.append(file)
+ db.commit()
+
+ # Set the service for the roles.
+ service = db.query(Service).filter_by(name='cyrus-imapd').first()
+ for role in db.query(Role).filter(
+ Role.name.in_(['imap-server-backend', 'imap-server-frontend'])
+ ).all():
+
+ role.services.append(service)
+ db.commit()
+
+ # Add setting 'admins' for file '/etc/imapd.conf' (no role)
+ setting = db.query(Setting).filter_by(key='admins').first()
+ if setting == None:
+ db.add(
+ Setting(
+ key='admins',
+ function="list_users_by_role('cyrus-admin', 'uid')"
+ )
+ )
+
+ db.commit()
+ setting = db.query(Setting).filter_by(key='admins').first()
+ file = db.query(File).filter_by(path='/etc/imapd.conf').first()
+ file.settings.append(setting)
+ db.commit()
+
+ # Add setting 'proxyservers' for file '/etc/imapd.conf' (role:
+ # imap-server-backend)
+ setting = db.query(Setting).filter_by(key='proxyservers').first()
+ if setting == None:
+ db.add(Setting(key='proxyservers', function="list_users_by_role('cyrus-proxyserver', 'uid')"))
+ db.commit()
+ setting = db.query(Setting).filter_by(key='proxyservers').first()
+ file = db.query(File).filter_by(path='/etc/imapd.conf').first()
+ file.settings.append(setting)
+ db.commit()
+
+ role = db.query(Role).filter_by(name='imap-server-backend').all()
+ setting.roles = role
+ db.commit()
+
+ # Add setting 'proxy_authname' for file '/etc/imapd.conf' (role:
+ # imap-server-frontend)
+ setting = db.query(Setting).filter_by(key='proxy_authname').first()
+ if setting == None:
+ # TODO: Somehow ensure that the value here is returned by the
+ # function for proxyservers as well!
+ db.add(Setting(key='proxy_authname', value='cyrus-murder'))
+ db.commit()
+ setting = db.query(Setting).filter_by(key='proxy_authname').first()
+ file = db.query(File).filter_by(path='/etc/imapd.conf').first()
+ file.settings.append(setting)
+ db.commit()
+
+ role = db.query(Role).filter_by(name='imap-server-frontend').all()
+ setting.roles = role
+ db.commit()
+
+ # Add setting 'proxy_password' for file '/etc/imapd.conf' (role:
+ # imap-server-frontend)
+ setting = db.query(Setting).filter_by(key='proxy_password').first()
+ if setting == None:
+ db.add(Setting(key='proxy_password', value='V3ryS3cr3t'))
+ db.commit()
+ setting = db.query(Setting).filter_by(key='proxy_password').first()
+ file = db.query(File).filter_by(path='/etc/imapd.conf').first()
+ file.settings.append(setting)
+ db.commit()
+
+ role = db.query(Role).filter_by(name='imap-server-frontend').all()
+ setting.roles = role
+ db.commit()
+
+ # Add setting 'serverlist' for file '/etc/imapd.conf' (role:
+ # imap-server-frontend)
+ setting = db.query(Setting).filter_by(key='serverlist').first()
+ if setting == None:
+ db.add(Setting(key='serverlist', function="list_nodes_by_role('imap-server-backend')"))
+ db.commit()
+ setting = db.query(Setting).filter_by(key='serverlist').first()
+ file = db.query(File).filter_by(path='/etc/imapd.conf').first()
+ file.settings.append(setting)
+ db.commit()
+
+ role = db.query(Role).filter_by(name='imap-server-frontend').all()
+ setting.roles = role
+ db.commit()
+
+ for node_fqdn in PRETEND_TO_HAVE_NODES:
+ print "Running for NODE FQDN %s" % (node_fqdn)
+
+ mynode = db.query(Node).filter_by(fqdn=node_fqdn).first()
+ myroles = mynode.roles
+
+ myservices = []
+ myfiles = []
+ mysettings = []
+
+ for myrole in myroles:
+ print "%-2s %s" % ('-', myrole.name)
+ print "role(%s) settings:" % (myrole.name), ', '.join([x.key for x in myrole.settings])
+
+ for _myservice in myrole.services:
+ print "role(%s) service(%s) files:" % (myrole.name, _myservice.name), ', '.join([x.path for x in _myservice.files])
+ if not _myservice in myservices:
+ myservices.append(_myservice)
+
+ for _myfile in _myservice.files:
+ print "role(%s) service(%s) file(%s) settings:" % (myrole.name,_myservice.name,_myfile.path), ', '.join([x.key for x in _myfile.settings])
+
+ if not _myfile in myfiles:
+ myfiles.append(_myfile)
+
+ for _mysetting in _myfile.settings:
+ if not _mysetting in mysettings:
+ if not _mysetting.roles == []:
+ for _role in _mysetting.roles:
+ if _role in myroles:
+ mysettings.append(_mysetting)
+ else:
+ mysettings.append(_mysetting)
+
+ for _mysetting in myrole.settings:
+ if not _mysetting in mysettings:
+ mysettings.append(_mysetting)
+
+ print "\nMy services:"
+
+ for myservice in myservices:
+ print "%-2s %s" % ('-', myservice.name)
+
+ print "\nMy files:"
+
+ for myfile in myfiles:
+ print "%-2s %s" % ('-', myfile.path)
+ if len(myfile.settings) > 0:
+ print "%-4s %s" % ('', "Related settings:")
+
+ for _mysetting in myfile.settings:
+ if len(_mysetting.roles) > 0:
+ is_my_role_too = False
+ for _role in _mysetting.roles:
+ if _role in myroles:
+ is_my_role_too = True
+
+ if not is_my_role_too:
+ continue
+
+ print "%-4s %s" % ('', _mysetting.key)
+
+ myaugeas = Augeas(flags=Augeas.SAVE_NEWFILE)
+
+ augeas_setting_path = '/files/%s/%s' % (myfile.path,_mysetting.key)
+
+ print "Using augeas setting path: %s" % (augeas_setting_path)
+
+ current_setting = myaugeas.get(augeas_setting_path)
+
+ print "Current setting:", current_setting
+
+ if not _mysetting.function == None:
+ exec("retval = %s" % (_mysetting.function))
+ new_setting = ' '.join(retval)
+ elif not _mysetting.value == None:
+ new_setting = _mysetting.value
+ else:
+ print "ERROR: No value nor function for setting %s" % (_mysetting.key)
+ continue
+
+ print "New setting:", new_setting
+
+ myaugeas.set(augeas_setting_path, new_setting)
+
+ myaugeas.save()
+
+ utils.ask_confirmation("Does this look alright?")
commit 38c2bf2ba44e48d5297c6bdf052c1cdfc50bcb9b
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date: Fri Dec 14 12:29:59 2012 +0000
Fix issuing len() on a possible None
diff --git a/pykolab/cli/sieve/cmd_refresh.py b/pykolab/cli/sieve/cmd_refresh.py
index 77eecc5..226fb93 100644
--- a/pykolab/cli/sieve/cmd_refresh.py
+++ b/pykolab/cli/sieve/cmd_refresh.py
@@ -258,7 +258,7 @@ def execute(*args, **kw):
mgmt_script.require(required_extension)
if vacation_active:
- if len(vacation_react_domains) > 0:
+ if not vacation_react_domains == None and len(vacation_react_domains) > 0:
mgmt_script.addfilter(
'vacation',
[('envelope', ':domain', ":is", "from", vacation_react_domains)],
@@ -275,7 +275,7 @@ def execute(*args, **kw):
]
)
- elif len(vacation_noreact_domains) > 0:
+ elif not vacation_noreact_domains == None and len(vacation_noreact_domains) > 0:
mgmt_script.addfilter(
'vacation',
[('not', ('envelope', ':domain', ":is", "from", vacation_noreact_domains))],
diff --git a/pykolab/plugins/sievemgmt/__init__.py b/pykolab/plugins/sievemgmt/__init__.py
index f341eae..1e22a47 100644
--- a/pykolab/plugins/sievemgmt/__init__.py
+++ b/pykolab/plugins/sievemgmt/__init__.py
@@ -271,7 +271,7 @@ class KolabSievemgmt(object):
mgmt_script.require(required_extension)
if vacation_active:
- if len(vacation_react_domains) > 0:
+ if not vacation_react_domains == None and len(vacation_react_domains) > 0:
mgmt_script.addfilter(
'vacation',
[('envelope', ':domain', ":is", "from", vacation_react_domains)],
@@ -288,7 +288,7 @@ class KolabSievemgmt(object):
]
)
- elif len(vacation_noreact_domains) > 0:
+ elif not vacation_noreact_domains == None and len(vacation_noreact_domains) > 0:
mgmt_script.addfilter(
'vacation',
[('not', ('envelope', ':domain', ":is", "from", vacation_noreact_domains))],
commit 1dd9c6570e4ef2b08523e8545d41c97830459624
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date: Wed Dec 12 13:41:48 2012 +0000
Make sure result_attr is obtained from our configuration before using the corresponding variable
diff --git a/ucs/kolab_sieve.py b/ucs/kolab_sieve.py
index b6d0349..f2b8df0 100755
--- a/ucs/kolab_sieve.py
+++ b/ucs/kolab_sieve.py
@@ -134,6 +134,7 @@ def handler(*args, **kw):
# See if the mailserver_attribute exists
mailserver_attribute = conf.get('ldap', 'mailserver_attribute').lower()
+ result_attr = conf.get('cyrus-sasl', 'result_attribute').lower()
if mailserver_attribute == None:
log.error("Mail server attribute is not set")
commit 9152aecc7c9a9ce98a0e0854002ef7d086fac26e
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date: Tue Dec 11 13:14:19 2012 +0000
Secure the SMTP server further, by verifying the envelope sender is either not locally hosted, or authenticated
diff --git a/pykolab/setup/setup_mta.py b/pykolab/setup/setup_mta.py
index 5c66f19..c02b024 100644
--- a/pykolab/setup/setup_mta.py
+++ b/pykolab/setup/setup_mta.py
@@ -198,6 +198,9 @@ result_attribute = mail
"transport_maps": "ldap:/etc/postfix/ldap/transport_maps.cf",
"virtual_alias_maps": "$alias_maps, ldap:/etc/postfix/ldap/virtual_alias_maps.cf, ldap:/etc/postfix/ldap/mailenabled_distgroups.cf, ldap:/etc/postfix/ldap/mailenabled_dynamic_distgroups.cf",
"smtpd_tls_auth_only": "yes",
+ "smtpd_sasl_auth_enable": "yes",
+ "smtpd_sender_login_maps": "$relay_recipient_maps",
+ "smtpd_sender_restrictions": "permit_mynetworks, reject_sender_login_mismatch",
"smtpd_recipient_restrictions": "permit_mynetworks, reject_unauth_pipelining, reject_rbl_client zen.spamhaus.org, reject_non_fqdn_recipient, reject_invalid_helo_hostname, reject_unknown_recipient_domain, reject_unauth_destination, check_policy_service unix:private/recipient_policy_incoming, permit",
"smtpd_sender_restrictions": "permit_mynetworks, check_policy_service unix:private/sender_policy_incoming",
"submission_recipient_restrictions": "check_policy_service unix:private/submission_policy, permit_sasl_authenticated, reject",
commit 5e895296887b134ca3d809a612ceccdc31795f78
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date: Tue Dec 11 13:13:33 2012 +0000
Lower-case the mailbox name for user mailboxes (#1455)
diff --git a/pykolab/imap/__init__.py b/pykolab/imap/__init__.py
index d0b7d08..1dcae4d 100644
--- a/pykolab/imap/__init__.py
+++ b/pykolab/imap/__init__.py
@@ -543,6 +543,10 @@ class IMAP(object):
"""
Check if a user mailbox exists.
"""
+ if not mailbox_base_name == mailbox_base_name.lower():
+ log.warning(_("Downcasing mailbox name %r") % (mailbox_base_name))
+ mailbox_base_name = mailbox_base_name.lower()
+
return self.has_folder('user%s%s' %(self.imap.separator, mailbox_base_name))
def user_mailbox_quota(self, mailbox_quota):
commit 70a3afdb2dd9175fbc7e7f8f155bca25e92fe42c
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date: Sun Dec 9 10:57:07 2012 +0000
Set the default username_domain so that users can login with mail and alias localparts
diff --git a/pykolab/setup/setup_roundcube.py b/pykolab/setup/setup_roundcube.py
index 5eed26c..1c1c60c 100644
--- a/pykolab/setup/setup_roundcube.py
+++ b/pykolab/setup/setup_roundcube.py
@@ -81,6 +81,7 @@ def execute(*args, **kw):
'ldap_service_bind_pw': conf.get('ldap', 'service_bind_pw'),
'ldap_user_base_dn': conf.get('ldap', 'user_base_dn'),
'ldap_user_filter': conf.get('ldap', 'user_filter'),
+ 'primary_domain': conf.get('kolab','primary_domain'),
'mysql_uri': 'mysqli://roundcube:%s@localhost/roundcube' % (mysql_roundcube_password),
'conf': conf
}
diff --git a/share/templates/roundcubemail/main.inc.php.tpl b/share/templates/roundcubemail/main.inc.php.tpl
index 89068ff..9e4d14f 100644
--- a/share/templates/roundcubemail/main.inc.php.tpl
+++ b/share/templates/roundcubemail/main.inc.php.tpl
@@ -195,7 +195,7 @@
\$rcmail_config['smtp_server'] = 'tls://localhost';
\$rcmail_config['session_domain'] = '';
\$rcmail_config['des_key'] = "$des_key";
- \$rcmail_config['username_domain'] = '';
+ \$rcmail_config['username_domain'] = '$primary_domain';
\$rcmail_config['mail_domain'] = '';
More information about the commits
mailing list