]> git.llucax.com Git - software/pymin.git/commitdiff
Add a ParametersHandler to services.util.
authorLeandro Lucarella <llucarella@integratech.com.ar>
Thu, 4 Oct 2007 14:35:40 +0000 (11:35 -0300)
committerLeandro Lucarella <llucarella@integratech.com.ar>
Thu, 4 Oct 2007 14:35:40 +0000 (11:35 -0300)
This class is a helper to provide common service parameters commands: get,
set, list and show.

All service handlers that use parameters were update to inherit from this
class.

services/dhcp/__init__.py
services/dns/__init__.py
services/firewall/__init__.py
services/proxy/__init__.py
services/util.py

index 7ffadcf7a4dc424a421bb6d77fc2b71d8df8f76e..8bed88329314e42244f368b77aead6045d57e1ef 100644 (file)
@@ -5,10 +5,10 @@ from os import path
 from seqtools import Sequence
 from dispatcher import Handler, handler, HandlerError
 from services.util import Restorable, ConfigWriter
 from seqtools import Sequence
 from dispatcher import Handler, handler, HandlerError
 from services.util import Restorable, ConfigWriter
-from services.util import InitdHandler, TransactionalHandler
+from services.util import InitdHandler, TransactionalHandler, ParametersHandler
 
 __ALL__ = ('DhcpHandler', 'Error', 'HostError', 'HostAlreadyExistsError',
 
 __ALL__ = ('DhcpHandler', 'Error', 'HostError', 'HostAlreadyExistsError',
-            'HostNotFoundError', 'ParameterError', 'ParameterNotFoundError')
+            'HostNotFoundError')
 
 class Error(HandlerError):
     r"""
 
 class Error(HandlerError):
     r"""
@@ -61,29 +61,6 @@ class HostNotFoundError(HostError):
         r"Initialize the object. See class documentation for more info."
         self.message = 'Host not found: "%s"' % hostname
 
         r"Initialize the object. See class documentation for more info."
         self.message = 'Host not found: "%s"' % hostname
 
-class ParameterError(Error, KeyError):
-    r"""
-    ParameterError(paramname) -> ParameterError instance
-
-    This is the base exception for all DhcpHandler parameters related errors.
-    """
-
-    def __init__(self, paramname):
-        r"Initialize the object. See class documentation for more info."
-        self.message = 'Parameter error: "%s"' % paramname
-
-class ParameterNotFoundError(ParameterError):
-    r"""
-    ParameterNotFoundError(hostname) -> ParameterNotFoundError instance
-
-    This exception is raised when trying to operate on a parameter that doesn't
-    exists.
-    """
-
-    def __init__(self, paramname):
-        r"Initialize the object. See class documentation for more info."
-        self.message = 'Parameter not found: "%s"' % paramname
-
 
 class Host(Sequence):
     r"""Host(name, ip, mac) -> Host instance :: Class representing a host.
 
 class Host(Sequence):
     r"""Host(name, ip, mac) -> Host instance :: Class representing a host.
@@ -157,7 +134,8 @@ class HostHandler(Handler):
         r"show() -> list of Hosts :: List all the complete hosts information."
         return self.hosts.values()
 
         r"show() -> list of Hosts :: List all the complete hosts information."
         return self.hosts.values()
 
-class DhcpHandler(Restorable, ConfigWriter, InitdHandler, TransactionalHandler):
+class DhcpHandler(Restorable, ConfigWriter, InitdHandler, TransactionalHandler,
+                  ParametersHandler):
     r"""DhcpHandler([pickle_dir[, config_dir]]) -> DhcpHandler instance.
 
     Handles DHCP service commands for the dhcpd program.
     r"""DhcpHandler([pickle_dir[, config_dir]]) -> DhcpHandler instance.
 
     Handles DHCP service commands for the dhcpd program.
@@ -171,11 +149,11 @@ class DhcpHandler(Restorable, ConfigWriter, InitdHandler, TransactionalHandler):
 
     _initd_name = 'dhcpd'
 
 
     _initd_name = 'dhcpd'
 
-    _persistent_vars = ('vars', 'hosts')
+    _persistent_vars = ('params', 'hosts')
 
     _restorable_defaults = dict(
             hosts = dict(),
 
     _restorable_defaults = dict(
             hosts = dict(),
-            vars  = dict(
+            params  = dict(
                 domain_name = 'example.com',
                 dns_1       = 'ns1.example.com',
                 dns_2       = 'ns2.example.com',
                 domain_name = 'example.com',
                 dns_1       = 'ns1.example.com',
                 dns_2       = 'ns2.example.com',
@@ -199,31 +177,7 @@ class DhcpHandler(Restorable, ConfigWriter, InitdHandler, TransactionalHandler):
         self.host = HostHandler(self.hosts)
 
     def _get_config_vars(self, config_file):
         self.host = HostHandler(self.hosts)
 
     def _get_config_vars(self, config_file):
-        return dict(hosts=self.hosts.values(), **self.vars)
-
-    @handler(u'Set a DHCP parameter.')
-    def set(self, param, value):
-        r"set(param, value) -> None :: Set a DHCP parameter."
-        if not param in self.vars:
-            raise ParameterNotFoundError(param)
-        self.vars[param] = value
-
-    @handler(u'Get a DHCP parameter.')
-    def get(self, param):
-        r"get(param) -> None :: Get a DHCP parameter."
-        if not param in self.vars:
-            raise ParameterNotFoundError(param)
-        return self.vars[param]
-
-    @handler(u'List all available DHCP parameters.')
-    def list(self):
-        r"list() -> tuple :: List all the parameter names."
-        return self.vars.keys()
-
-    @handler(u'Get all DHCP parameters, with their values.')
-    def show(self):
-        r"show() -> (key, value) tuples :: List all the parameters."
-        return self.vars.items()
+        return dict(hosts=self.hosts.values(), **self.params)
 
 if __name__ == '__main__':
 
 
 if __name__ == '__main__':
 
index e3739e382a0767784c92e0a5fcdcf7f5b930550c..ce21e97e7994fc40765484114e61f7bef7a5701a 100644 (file)
@@ -8,15 +8,14 @@ from new import instancemethod
 from seqtools import Sequence
 from dispatcher import handler, HandlerError, Handler
 from services.util import Restorable, ConfigWriter, call
 from seqtools import Sequence
 from dispatcher import handler, HandlerError, Handler
 from services.util import Restorable, ConfigWriter, call
-from services.util import InitdHandler, TransactionalHandler
+from services.util import InitdHandler, TransactionalHandler, ParametersHandler
 
 __ALL__ = ('DnsHandler', 'Error',
             'ZoneError', 'ZoneNotFoundError', 'ZoneAlreadyExistsError',
             'HostError', 'HostAlreadyExistsError', 'HostNotFoundError',
             'MailExchangeError', 'MailExchangeAlreadyExistsError',
             'MailExchangeNotFoundError', 'NameServerError',
 
 __ALL__ = ('DnsHandler', 'Error',
             'ZoneError', 'ZoneNotFoundError', 'ZoneAlreadyExistsError',
             'HostError', 'HostAlreadyExistsError', 'HostNotFoundError',
             'MailExchangeError', 'MailExchangeAlreadyExistsError',
             'MailExchangeNotFoundError', 'NameServerError',
-            'NameServerAlreadyExistsError', 'NameServerNotFoundError',
-            'ParameterError', 'ParameterNotFoundError')
+            'NameServerAlreadyExistsError', 'NameServerNotFoundError')
 
 template_dir = path.join(path.dirname(__file__), 'templates')
 
 
 template_dir = path.join(path.dirname(__file__), 'templates')
 
@@ -396,7 +395,8 @@ class ZoneHandler(Handler):
     def show(self):
         return self.zones.values()
 
     def show(self):
         return self.zones.values()
 
-class DnsHandler(Restorable, ConfigWriter, InitdHandler, TransactionalHandler):
+class DnsHandler(Restorable, ConfigWriter, InitdHandler, TransactionalHandler,
+                 ParametersHandler):
     r"""DnsHandler([pickle_dir[, config_dir]]) -> DnsHandler instance.
 
     Handles DNS service commands for the dns program.
     r"""DnsHandler([pickle_dir[, config_dir]]) -> DnsHandler instance.
 
     Handles DNS service commands for the dns program.
@@ -410,11 +410,11 @@ class DnsHandler(Restorable, ConfigWriter, InitdHandler, TransactionalHandler):
 
     _initd_name = 'bind'
 
 
     _initd_name = 'bind'
 
-    _persistent_vars = ('vars', 'zones')
+    _persistent_vars = ('params', 'zones')
 
     _restorable_defaults = dict(
             zones = dict(),
 
     _restorable_defaults = dict(
             zones = dict(),
-            vars  = dict(
+            params  = dict(
                 isp_dns1 = '',
                 isp_dns2 = '',
                 bind_addr1 = '',
                 isp_dns1 = '',
                 isp_dns2 = '',
                 bind_addr1 = '',
@@ -437,34 +437,11 @@ class DnsHandler(Restorable, ConfigWriter, InitdHandler, TransactionalHandler):
         self.mx = MailExchangeHandler(self.zones)
         self.ns = NameServerHandler(self.zones)
 
         self.mx = MailExchangeHandler(self.zones)
         self.ns = NameServerHandler(self.zones)
 
-    @handler(u'Set a DNS parameter')
-    def set(self, param, value):
-        r"set(param, value) -> None :: Set a DNS parameter."
-        if not param in self.vars:
-            raise ParameterNotFoundError(param)
-        self.vars[param] = value
-        self.mod = True
-
-    @handler(u'Get a DNS parameter')
-    def get(self, param):
-        r"get(param) -> None :: Get a DNS parameter."
-        if not param in self.vars:
-            raise ParameterNotFoundError(param)
-        return self.vars[param]
-
-    @handler(u'List DNS parameters')
-    def list(self):
-        return self.vars.keys()
-
-    @handler(u'Get all DNS parameters, with their values.')
-    def show(self):
-        return self.vars.values()
-
     def _zone_filename(self, zone):
         return zone.name + '.zone'
 
     def _get_config_vars(self, config_file):
     def _zone_filename(self, zone):
         return zone.name + '.zone'
 
     def _get_config_vars(self, config_file):
-        return dict(zones=self.zones.values(), **self.vars)
+        return dict(zones=self.zones.values(), **self.params)
 
     def _write_config(self):
         r"_write_config() -> None :: Generate all the configuration files."
 
     def _write_config(self):
         r"_write_config() -> None :: Generate all the configuration files."
index bbdb3fd53f6a8943ad6ce339933660a5ae371e66..738bf67e82d7e79cfe44f147cb4322dd3d43130b 100644 (file)
@@ -7,8 +7,8 @@ from os import path
 
 from seqtools import Sequence
 from dispatcher import Handler, handler, HandlerError
 
 from seqtools import Sequence
 from dispatcher import Handler, handler, HandlerError
-from services.util import ServiceHandler, TransactionalHandler
 from services.util import Restorable, ConfigWriter
 from services.util import Restorable, ConfigWriter
+from services.util import ServiceHandler, TransactionalHandler
 
 __ALL__ = ('FirewallHandler', 'Error', 'RuleError', 'RuleAlreadyExistsError',
            'RuleNotFoundError')
 
 __ALL__ = ('FirewallHandler', 'Error', 'RuleError', 'RuleAlreadyExistsError',
            'RuleNotFoundError')
@@ -174,7 +174,7 @@ class RuleHandler(Handler):
         return self.rules
 
 class FirewallHandler(Restorable, ConfigWriter, ServiceHandler,
         return self.rules
 
 class FirewallHandler(Restorable, ConfigWriter, ServiceHandler,
-                                                        TransactionalHandler):
+                      TransactionalHandler):
     r"""FirewallHandler([pickle_dir[, config_dir]]) -> FirewallHandler instance.
 
     Handles firewall commands using iptables.
     r"""FirewallHandler([pickle_dir[, config_dir]]) -> FirewallHandler instance.
 
     Handles firewall commands using iptables.
index 195125c5dfbb34d5730a915207ed343a0e0555bb..60548871886c13aac612a98783f2b60007da4283 100644 (file)
@@ -5,7 +5,7 @@ from os import path
 from seqtools import Sequence
 from dispatcher import Handler, handler, HandlerError
 from services.util import Restorable, ConfigWriter
 from seqtools import Sequence
 from dispatcher import Handler, handler, HandlerError
 from services.util import Restorable, ConfigWriter
-from services.util import InitdHandler, TransactionalHandler
+from services.util import InitdHandler, TransactionalHandler, ParametersHandler
 
 __ALL__ = ('ProxyHandler', 'Error', 'HostError', 'HostAlreadyExistsError',
             'HostNotFoundError', 'ParameterError', 'ParameterNotFoundError')
 
 __ALL__ = ('ProxyHandler', 'Error', 'HostError', 'HostAlreadyExistsError',
             'HostNotFoundError', 'ParameterError', 'ParameterNotFoundError')
@@ -119,15 +119,15 @@ class HostHandler(Handler):
 
 
 class ProxyHandler(Restorable, ConfigWriter, InitdHandler,
 
 
 class ProxyHandler(Restorable, ConfigWriter, InitdHandler,
-                                            TransactionalHandler):
+                   TransactionalHandler, ParametersHandler):
 
     _initd_name = 'squid'
 
 
     _initd_name = 'squid'
 
-    _persistent_vars = ('vars', 'hosts')
+    _persistent_vars = ('params', 'hosts')
 
     _restorable_defaults = dict(
             hosts = dict(),
 
     _restorable_defaults = dict(
             hosts = dict(),
-            vars  = dict(
+            params  = dict(
                 ip   = '192.168.0.1',
                 port = '8080',
             ),
                 ip   = '192.168.0.1',
                 port = '8080',
             ),
@@ -145,29 +145,7 @@ class ProxyHandler(Restorable, ConfigWriter, InitdHandler,
         self.host = HostHandler(self.hosts)
 
     def _get_config_vars(self, config_file):
         self.host = HostHandler(self.hosts)
 
     def _get_config_vars(self, config_file):
-        return dict(hosts=self.hosts.values(), **self.vars)
-
-    @handler(u'Set a Proxy parameter')
-    def set(self, param, value):
-        r"set(param, value) -> None :: Set a Proxy parameter."
-        if not param in self.vars:
-            raise ParameterNotFoundError(param)
-        self.vars[param] = value
-
-    @handler(u'Get a DNS parameter')
-    def get(self, param):
-        r"get(param) -> None :: Get a Proxy parameter."
-        if not param in self.vars:
-            raise ParameterNotFoundError(param)
-        return self.vars[param]
-
-    @handler(u'List Proxy parameters')
-    def list(self):
-        return self.vars.keys()
-
-    @handler(u'Get all Proxy parameters, with their values.')
-    def show(self):
-        return self.vars.values()
+        return dict(hosts=self.hosts.values(), **self.params)
 
 
 if __name__ == '__main__':
 
 
 if __name__ == '__main__':
index cbfc091032653cfb784fd206b47477ab6e017eb8..4468384c2152f234cd1dc4a91c1a5ccd6f92d419 100644 (file)
@@ -72,6 +72,29 @@ class ExecutionError(Error):
             command = ' '.join(command)
         return "Can't execute command %s: %s" % (command, self.error)
 
             command = ' '.join(command)
         return "Can't execute command %s: %s" % (command, self.error)
 
+class ParameterError(Error, KeyError):
+    r"""
+    ParameterError(paramname) -> ParameterError instance
+
+    This is the base exception for all DhcpHandler parameters related errors.
+    """
+
+    def __init__(self, paramname):
+        r"Initialize the object. See class documentation for more info."
+        self.message = 'Parameter error: "%s"' % paramname
+
+class ParameterNotFoundError(ParameterError):
+    r"""
+    ParameterNotFoundError(hostname) -> ParameterNotFoundError instance
+
+    This exception is raised when trying to operate on a parameter that doesn't
+    exists.
+    """
+
+    def __init__(self, paramname):
+        r"Initialize the object. See class documentation for more info."
+        self.message = 'Parameter not found: "%s"' % paramname
+
 def call(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
             stderr=subprocess.PIPE, close_fds=True, universal_newlines=True,
             **kw):
 def call(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
             stderr=subprocess.PIPE, close_fds=True, universal_newlines=True,
             **kw):
@@ -89,108 +112,6 @@ def call(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
     if r is not 0:
         raise ExecutionError(command, ReturnNot0Error(r))
 
     if r is not 0:
         raise ExecutionError(command, ReturnNot0Error(r))
 
-class ServiceHandler(Handler):
-    r"""ServiceHandler([start[, stop[, restart[, reload]]]]) -> ServiceHandler.
-
-    This is a helper class to inherit from to automatically handle services
-    with start, stop, restart, reload actions.
-
-    The actions can be defined by calling the constructor with all the
-    parameters or in a more declarative way as class attributes, like:
-
-    class TestHandler(ServiceHandler):
-        _service_start = ('command', 'start')
-        _service_stop = ('command', 'stop')
-        _service_restart = ('command', 'restart')
-        _service_reload = 'reload-command'
-
-    Commands are executed without using the shell, that's why they are specified
-    as tuples (where the first element is the command and the others are the
-    command arguments). If only a command is needed (without arguments) a single
-    string can be specified.
-
-    All commands must be specified.
-    """
-    # TODO implement it using metaclasses to add the handlers method by demand
-    # (only for specifieds commands).
-
-    def __init__(self, start=None, stop=None, restart=None, reload=None):
-        r"Initialize the object, see the class documentation for details."
-        for (name, action) in dict(start=start, stop=stop, restart=restart,
-                                                    reload=reload).items():
-            if action is not None:
-                setattr(self, '_service_%s' % name, action)
-
-    @handler(u'Start the service.')
-    def start(self):
-        r"start() -> None :: Start the service."
-        call(self._service_start)
-
-    @handler(u'Stop the service.')
-    def stop(self):
-        r"stop() -> None :: Stop the service."
-        call(self._service_stop)
-
-    @handler(u'Restart the service.')
-    def restart(self):
-        r"restart() -> None :: Restart the service."
-        call(self._service_restart)
-
-    @handler(u'Reload the service config (without restarting, if possible).')
-    def reload(self):
-        r"reload() -> None :: Reload the configuration of the service."
-        call(self._service_reload)
-
-class InitdHandler(Handler):
-    r"""InitdHandler([initd_name[, initd_dir]]) -> InitdHandler.
-
-    This is a helper class to inherit from to automatically handle services
-    with start, stop, restart, reload actions using a /etc/init.d like script.
-
-    The name and directory of the script can be defined by calling the
-    constructor or in a more declarative way as class attributes, like:
-
-    class TestHandler(ServiceHandler):
-        _initd_name = 'some-service'
-        _initd_dir = '/usr/local/etc/init.d'
-
-    The default _initd_dir is '/etc/init.d', _initd_name has no default and
-    must be specified in either way.
-
-    Commands are executed without using the shell.
-    """
-    # TODO implement it using metaclasses to add the handlers method by demand
-    # (only for specifieds commands).
-
-    _initd_dir = '/etc/init.d'
-
-    def __init__(self, initd_name=None, initd_dir=None):
-        r"Initialize the object, see the class documentation for details."
-        if initd_name is not None:
-            self._initd_name = initd_name
-        if initd_dir is not None:
-            self._initd_dir = initd_dir
-
-    @handler(u'Start the service.')
-    def start(self):
-        r"start() -> None :: Start the service."
-        call((path.join(self._initd_dir, self._initd_name), 'start'))
-
-    @handler(u'Stop the service.')
-    def stop(self):
-        r"stop() -> None :: Stop the service."
-        call((path.join(self._initd_dir, self._initd_name), 'stop'))
-
-    @handler(u'Restart the service.')
-    def restart(self):
-        r"restart() -> None :: Restart the service."
-        call((path.join(self._initd_dir, self._initd_name), 'restart'))
-
-    @handler(u'Reload the service config (without restarting, if possible).')
-    def reload(self):
-        r"reload() -> None :: Reload the configuration of the service."
-        call((path.join(self._initd_dir, self._initd_name), 'reload'))
-
 class Persistent:
     r"""Persistent([vars[, dir[, ext]]]) -> Persistent.
 
 class Persistent:
     r"""Persistent([vars[, dir[, ext]]]) -> Persistent.
 
@@ -419,8 +340,110 @@ class ConfigWriter:
         for t in self._config_writer_files:
             self._write_single_config(t)
 
         for t in self._config_writer_files:
             self._write_single_config(t)
 
+class ServiceHandler(Handler):
+    r"""ServiceHandler([start[, stop[, restart[, reload]]]]) -> ServiceHandler.
+
+    This is a helper class to inherit from to automatically handle services
+    with start, stop, restart, reload actions.
+
+    The actions can be defined by calling the constructor with all the
+    parameters or in a more declarative way as class attributes, like:
+
+    class TestHandler(ServiceHandler):
+        _service_start = ('command', 'start')
+        _service_stop = ('command', 'stop')
+        _service_restart = ('command', 'restart')
+        _service_reload = 'reload-command'
+
+    Commands are executed without using the shell, that's why they are specified
+    as tuples (where the first element is the command and the others are the
+    command arguments). If only a command is needed (without arguments) a single
+    string can be specified.
+
+    All commands must be specified.
+    """
+    # TODO implement it using metaclasses to add the handlers method by demand
+    # (only for specifieds commands).
+
+    def __init__(self, start=None, stop=None, restart=None, reload=None):
+        r"Initialize the object, see the class documentation for details."
+        for (name, action) in dict(start=start, stop=stop, restart=restart,
+                                                    reload=reload).items():
+            if action is not None:
+                setattr(self, '_service_%s' % name, action)
+
+    @handler(u'Start the service.')
+    def start(self):
+        r"start() -> None :: Start the service."
+        call(self._service_start)
+
+    @handler(u'Stop the service.')
+    def stop(self):
+        r"stop() -> None :: Stop the service."
+        call(self._service_stop)
+
+    @handler(u'Restart the service.')
+    def restart(self):
+        r"restart() -> None :: Restart the service."
+        call(self._service_restart)
+
+    @handler(u'Reload the service config (without restarting, if possible).')
+    def reload(self):
+        r"reload() -> None :: Reload the configuration of the service."
+        call(self._service_reload)
+
+class InitdHandler(Handler):
+    r"""InitdHandler([initd_name[, initd_dir]]) -> InitdHandler.
+
+    This is a helper class to inherit from to automatically handle services
+    with start, stop, restart, reload actions using a /etc/init.d like script.
+
+    The name and directory of the script can be defined by calling the
+    constructor or in a more declarative way as class attributes, like:
+
+    class TestHandler(ServiceHandler):
+        _initd_name = 'some-service'
+        _initd_dir = '/usr/local/etc/init.d'
+
+    The default _initd_dir is '/etc/init.d', _initd_name has no default and
+    must be specified in either way.
+
+    Commands are executed without using the shell.
+    """
+    # TODO implement it using metaclasses to add the handlers method by demand
+    # (only for specifieds commands).
+
+    _initd_dir = '/etc/init.d'
+
+    def __init__(self, initd_name=None, initd_dir=None):
+        r"Initialize the object, see the class documentation for details."
+        if initd_name is not None:
+            self._initd_name = initd_name
+        if initd_dir is not None:
+            self._initd_dir = initd_dir
+
+    @handler(u'Start the service.')
+    def start(self):
+        r"start() -> None :: Start the service."
+        call((path.join(self._initd_dir, self._initd_name), 'start'))
+
+    @handler(u'Stop the service.')
+    def stop(self):
+        r"stop() -> None :: Stop the service."
+        call((path.join(self._initd_dir, self._initd_name), 'stop'))
+
+    @handler(u'Restart the service.')
+    def restart(self):
+        r"restart() -> None :: Restart the service."
+        call((path.join(self._initd_dir, self._initd_name), 'restart'))
+
+    @handler(u'Reload the service config (without restarting, if possible).')
+    def reload(self):
+        r"reload() -> None :: Reload the configuration of the service."
+        call((path.join(self._initd_dir, self._initd_name), 'reload'))
+
 class TransactionalHandler(Handler):
 class TransactionalHandler(Handler):
-    r"""TransactionalHandler([initd_name[, initd_dir]]) -> TransactionalHandler.
+    r"""Handle command transactions providing a commit and rollback commands.
 
     This is a helper class to inherit from to automatically handle
     transactional handlers, which have commit and rollback commands.
 
     This is a helper class to inherit from to automatically handle
     transactional handlers, which have commit and rollback commands.
@@ -451,6 +474,54 @@ class TransactionalHandler(Handler):
         if hasattr(self, '_load'):
             self._load()
 
         if hasattr(self, '_load'):
             self._load()
 
+class ParametersHandler(Handler):
+    r"""ParametersHandler([attr]) -> ParametersHandler.
+
+    This is a helper class to inherit from to automatically handle
+    service parameters, providing set, get, list and show commands.
+
+    The attribute that holds the parameters can be defined by calling the
+    constructor or in a more declarative way as class attributes, like:
+
+    class TestHandler(ServiceHandler):
+        _parameters_attr = 'some_attr'
+
+    The default is 'params' and it should be a dictionary.
+    """
+    # TODO implement it using metaclasses to add the handlers method by demand
+    # (only for specifieds commands).
+
+    _parameters_attr = 'params'
+
+    def __init__(self, attr=None):
+        r"Initialize the object, see the class documentation for details."
+        if attr is not None:
+            self._parameters_attr = attr
+
+    @handler(u'Set a service parameter.')
+    def set(self, param, value):
+        r"set(param, value) -> None :: Set a service parameter."
+        if not param in self.params:
+            raise ParameterNotFoundError(param)
+        self.params[param] = value
+
+    @handler(u'Get a service parameter.')
+    def get(self, param):
+        r"get(param) -> None :: Get a service parameter."
+        if not param in self.params:
+            raise ParameterNotFoundError(param)
+        return self.params[param]
+
+    @handler(u'List all available service parameters.')
+    def list(self):
+        r"list() -> tuple :: List all the parameter names."
+        return self.params.keys()
+
+    @handler(u'Get all service parameters, with their values.')
+    def show(self):
+        r"show() -> (key, value) tuples :: List all the parameters."
+        return self.params.items()
+
 
 if __name__ == '__main__':
 
 
 if __name__ == '__main__':