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',
- 'HostNotFoundError', 'ParameterError', 'ParameterNotFoundError')
+ 'HostNotFoundError')
class Error(HandlerError):
r"""
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.
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.
_initd_name = 'dhcpd'
- _persistent_vars = ('vars', 'hosts')
+ _persistent_vars = ('params', 'hosts')
_restorable_defaults = dict(
hosts = dict(),
- vars = dict(
+ params = dict(
domain_name = 'example.com',
dns_1 = 'ns1.example.com',
dns_2 = 'ns2.example.com',
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__':
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',
- 'NameServerAlreadyExistsError', 'NameServerNotFoundError',
- 'ParameterError', 'ParameterNotFoundError')
+ 'NameServerAlreadyExistsError', 'NameServerNotFoundError')
template_dir = path.join(path.dirname(__file__), 'templates')
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.
_initd_name = 'bind'
- _persistent_vars = ('vars', 'zones')
+ _persistent_vars = ('params', 'zones')
_restorable_defaults = dict(
zones = dict(),
- vars = dict(
+ params = dict(
isp_dns1 = '',
isp_dns2 = '',
bind_addr1 = '',
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):
- 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."
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):
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.
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):
- 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.
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__':