Ideas / TODO:
-* Hacer el protocolo completamente introspectivo, de manera que el cliente pueda
- ser muy simple y genérico y en caso de agregar funcionalidad no sea necesario
- modificarlo.
-
-* Evaluar hacer un RootHandler en vez de un diccionario con los handlers de la
- raiz para simplificar la introspección y tener un help/commands global.
-
-* Evaluar que el dispatcher vea si se llama a un HandlerContainer y de ser así
- que tire una ayuda en vez de un CommandNotFound (por ejemplo si se pone:
- "dhcp" solo que tire una ayuda). Y si hay un subcomando no encontrado, que
- tire un Command Not Found in handler (por ej "dhcp lala" -> Command "lala" not
- found in "dhcp").
-
* Agregar logging.
* Agregar validación con formencode.
# vim: set et sts=4 sw=4 encoding=utf-8 :
from pymin.services import *
-from pymin.dispatcher import handler
+from pymin.dispatcher import Handler
+from os.path import join
-# XXX for testing only
-@handler
-def test_func(*args):
- print 'func:', args
+base_path = join('var', 'lib', 'pymin')
+pickle_path = join(base_path, 'pickle')
+# FIXME, this should be specific for each service
+config_path = join(base_path, 'config')
-routes = dict \
-(
+class Root(Handler):
dhcp = DhcpHandler(
- pickle_dir = 'var/lib/pymin/pickle/dhcp',
- config_dir = 'var/lib/pymin/config/dhcp',
- ),
+ pickle_dir = join(pickle_path, 'dhcp'),
+ config_dir = join(config_path, 'dhcp'))
dns = DnsHandler(
- pickle_dir = 'var/lib/pymin/pickle/dns',
- config_dir = 'var/lib/pymin/config/dns',
- ),
+ pickle_dir = join(pickle_path, 'dns'),
+ config_dir = join(config_path, 'dns'))
firewall = FirewallHandler(
- pickle_dir = 'var/lib/pymin/pickle/firewall',
- config_dir = 'var/lib/pymin/config/firewall',
- ),
+ pickle_dir = join(pickle_path, 'firewall'),
+ config_dir = join(config_path, 'firewall'))
ip = IpHandler(
- pickle_dir = 'var/lib/pymin/pickle/ip',
- config_dir = 'var/lib/pymin/config/ip',
- ),
+ pickle_dir = join(pickle_path, 'ip'),
+ config_dir = join(config_path, 'ip'))
proxy = ProxyHandler(
- pickle_dir = 'var/lib/pymin/pickle/proxy',
- config_dir = 'var/lib/pymin/config/proxy',
- ),
-)
+ pickle_dir = join(pickle_path, 'proxy'),
+ config_dir = join(config_path, 'proxy'))
bind_addr = \
(
--- /dev/null
+Configruacion de iptables:
+
+1) Listar las reglas de una tabla
+
+# iptables -t ${table} -L -v
+
+2) Para listar reglas de fitrado
+
+# iptables -t filter -L -v
+
+2.1) Agregar una regla de filtrado
+
+# iptables -t filter -I ${chain} ${pos} -j ${target} [-s ${src_ip}/${src_ip_prefix_length}] [-d ${dest_ip}/${dst_ip_prefix_length}] [-p ${protocol}]
+
+Si el protocolo (opcion -p) es udp o tcp se puede agregar los puertos de origen o destino
+
+# iptables -t filter -I ${chain} ${num} -j ${target} [-s ${src_ip}/${src_ip_prefix_length}] [-d ${dest_ip}/${dst_ip_prefix_length}] [-p ${protocol}] -m ${protocolo} [--sport ${src_port}] [--dport ${dst_port}]
+
+Donde:
+- ${chain} es INPUT, OUTPUT o FORWARD
+- ${pos} es el numero de regla dentro de la tabla
+- ${protocol} es udp, tcp, icmp o all
+- ${target} es DROP, ACCEPT, REJECT
+
+2.1) Eliminar una regla de una tabla
+
+# iptables -t ${table} -D ${chain} ${num}
+
+2.2) Eliminar todas las reglas de una tabla
+
+# iptables -t ${table} -F
+
+2.3) Eliminar todas las reglas dentro de una cadena de una tabla
+
+# iptables -t ${table} -F ${chain}
command - is the command that raised the exception, expressed as a list of
paths (or subcommands).
"""
- pass
+
+ def __init__(self, message):
+ r"Initialize the Error object. See class documentation for more info."
+ self.message = message
+
+ def __unicode__(self):
+ return self.message
+
+ def __str__(self):
+ return unicode(self).encode('utf-8')
class HandlerError(Error):
r"""HandlerError(command) -> HandlerError instance :: Base handlers error.
"""
def __init__(self, command):
- r"""Initialize the object.
-
- See class documentation for more info.
- """
+ r"Initialize the object, see class documentation for more info."
self.command = command
- def __str__(self):
- return 'Command error: "%s"' % self.command
+ def __unicode__(self):
+ return u'Error in command "%s".' % u' '.join(self.command)
+
+class CommandNotSpecifiedError(CommandError):
+ r"""CommandNotSpecifiedError() -> CommandNotSpecifiedError instance.
+
+ This exception is raised when an empty command string is received.
+ """
+
+ def __init__(self):
+ r"Initialize the object, see class documentation for more info."
+ pass
+
+ def __unicode__(self):
+ return u'Command not specified.'
+
+class CommandIsAHandlerError(CommandError):
+ r"""CommandIsAHandlerError() -> CommandIsAHandlerError instance.
+
+ This exception is raised when a command is a handler containing commands
+ instead of a command itself.
+ """
+
+ def __unicode__(self):
+ command = ' '.join(self.command)
+ return u'"%s" is a handler, not a command (type "%s help" for help).' \
+ % (command, command)
+
+class CommandNotInHandlerError(CommandError):
+ r"""CommandNotInHandlerError() -> CommandNotInHandlerError instance.
+
+ This exception is raised when a command parent is a hanlder containing
+ commands, but the command itself is not found.
+ """
+
+ def __unicode__(self):
+ return u'Command "%(c)s" not found in handler "%(h)s" ' \
+ u'(type "%(h)s help" for help).' \
+ % dict(c=u' '.join(self.command[-1:]),
+ h=u' '.join(self.command[0:-1]))
class CommandNotFoundError(CommandError):
- r"""CommandNotFoundError(command) -> CommandNotFoundError instance.
+ r"""CommandNotFoundError(command[, handler]) -> CommandNotFoundError object.
This exception is raised when the command received can't be dispatched
because there is no handlers to process it.
"""
- def __str__(self):
- return 'Command not found: "%s"' % ' '.join(
- repr(c) for c in self.command)
+ def __unicode__(self):
+ return u'Command "%s" not found.' % u' '.join(self.command)
class ParseError(CommandError):
r"""ParseError(command[, desc]) -> ParseError instance
self.command = command
self.desc = desc
- def __str__(self):
- return 'Syntax error, %s: %s' % (self.desc, self.command)
+ def __unicode__(self):
+ return u'Syntax error, %s: %s' % (self.desc, self.command)
+
+class HelpNotFoundError(Error):
+ r"""HelpNotFoundError(command) -> HelpNotFoundError instance.
+
+ This exception is raised when a help command can't find the command
+ asked for help.
+ """
+
+ def __init__(self, command):
+ r"""Initialize the object.
+
+ See class documentation for more info.
+ """
+ self.command = command
+
+ def __unicode__(self):
+ return u"Can't get help for '%s', command not found." % self.command
+
def handler(help):
r"""handler(help) -> function wrapper :: Mark a callable as a handler.
def wrapper(f):
if not help:
raise TypeError("'help' should not be empty")
- f._dispatcher_help = help
+ f._dispatcher_handler = True
+ f.handler_help = help
return f
return wrapper
def is_handler(handler):
r"is_handler(handler) -> bool :: Tell if a object is a handler."
- return callable(handler) and hasattr(handler, '_dispatcher_help')
-
-def get_help(handler):
- r"get_help(handler) -> unicode :: Get a handler's help string."
- if not is_handler(handler):
- raise TypeError("'%s' should be a handler" % handler.__name__)
- return handler._dispatcher_help
+ return callable(handler) and hasattr(handler, '_dispatcher_handler') \
+ and handler._dispatcher_handler
class Handler:
r"""Handler() -> Handler instance :: Base class for all dispatcher handlers.
All dispatcher handlers should inherit from this class to have some extra
- commands, like help.
+ commands, like help. You should override the 'handler_help' attribute to a
+ nice help message describing the handler.
"""
- @handler(u'List available commands.')
+ handler_help = u'Undocumented handler'
+
+ @handler(u'List available commands')
def commands(self):
r"""commands() -> generator :: List the available commands."""
return (a for a in dir(self) if is_handler(getattr(self, a)))
- @handler(u'Show available commands with their help.')
+ @handler(u'Show available commands with their help')
def help(self, command=None):
r"""help([command]) -> unicode/dict :: Show help on available commands.
and values are the help strings.
"""
if command is None:
- return dict((a, get_help(getattr(self, a)))
- for a in dir(self) if is_handler(getattr(self, a)))
- if not hasattr(self, command):
- raise CommandNotFoundError(command)
- handler = getattr(self, command)
- if not is_handler(handler):
- raise CommandNotFoundError(command)
- return get_help(handler)
+ d = dict()
+ for a in dir(self):
+ h = getattr(self, a)
+ if is_handler(h) or isinstance(h, Handler):
+ d[a] = h.handler_help
+ return d
+ # A command was specified
+ if not hasattr(self, command.encode('utf-8')):
+ raise HelpNotFoundError(command)
+ handler = getattr(self, command.encode('utf-8'))
+ if not is_handler(handler) and not hasattr(handler):
+ raise HelpNotFoundError(command)
+ return handler.handler_help
def parse_command(command):
r"""parse_command(command) -> (args, kwargs) :: Parse a command.
return (seq, dic)
class Dispatcher:
- r"""Dispatcher([routes]) -> Dispatcher instance :: Command dispatcher
+ r"""Dispatcher([root]) -> Dispatcher instance :: Command dispatcher.
This class provides a modular and extensible dispatching mechanism. You
- can specify root 'routes' (as a dict where the key is the string of the
- root command and the value is a callable object to handle that command,
- or a subcommand if the callable is an instance and the command can be
- sub-routed).
+ specify a root handler (probably as a pymin.dispatcher.Handler subclass),
- The command can have arguments, separated by (any number of) spaces.
+ The command can have arguments, separated by (any number of) spaces and
+ keyword arguments (see parse_command for more details).
The dispatcher tries to route the command as deeply as it can, passing
the other "path" components as arguments to the callable. To route the
Example:
>>> d = Dispatcher(dict(handler=some_handler))
- >>> d.dispatch('handler attribute method arg1 arg2 "third argument"')
+ >>> d.dispatch('handler attribute method arg1 "arg 2" arg=3')
If 'some_handler' is an object with an 'attribute' that is another
object which has a method named 'method', then
- some_handler.attribute.method('arg1', 'arg2') will be called. If
- some_handler is a function, then some_handler('attribute', 'method',
- 'arg1', 'arg2') will be called. The handler "tree" can be as complex
- and deep as you want.
+ some_handler.attribute.method('arg1', 'arg 2', arg=3) will be called.
+ If some_handler is a function, then some_handler('attribute', 'method',
+ 'arg1', 'arg 2', arg=3) will be called. The handler "tree" can be as
+ complex and deep as you want.
- If some command can't be dispatched (because there is no root handler or
- there is no matching callable attribute), a CommandNotFoundError is raised.
+ If some command can't be dispatched, a CommandError subclass is raised.
"""
- def __init__(self, routes=dict()):
+ def __init__(self, root):
r"""Initialize the Dispatcher object.
See Dispatcher class documentation for more info.
"""
- self.routes = routes
+ self.root = root
def dispatch(self, route):
r"""dispatch(route) -> None :: Dispatch a command string.
This method searches for a suitable callable object in the routes
- "tree" and call it, or raises a CommandNotFoundError if the command
+ "tree" and call it, or raises a CommandError subclass if the command
can't be dispatched.
+
+ route - *unicode* string with the command route.
"""
command = list()
(route, kwargs) = parse_command(route)
if not route:
- raise CommandNotFoundError(command)
- command.append(route[0])
- handler = self.routes.get(route[0], None)
- if handler is None:
- raise CommandNotFoundError(command)
- route = route[1:]
+ raise CommandNotSpecifiedError()
+ handler = self.root
while not is_handler(handler):
if len(route) is 0:
+ if isinstance(handler, Handler):
+ raise CommandIsAHandlerError(command)
raise CommandNotFoundError(command)
command.append(route[0])
- if not hasattr(handler, route[0]):
+ if not hasattr(handler, route[0].encode('utf-8')):
+ if isinstance(handler, Handler) and len(command) > 1:
+ raise CommandNotInHandlerError(command)
raise CommandNotFoundError(command)
- handler = getattr(handler, route[0])
+ handler = getattr(handler, route[0].encode('utf-8'))
route = route[1:]
return handler(*route, **kwargs)
if __name__ == '__main__':
- @handler(u"test: Print all the arguments, return nothing.")
+ @handler(u"test: Print all the arguments, return nothing")
def test_func(*args):
print 'func:', args
class TestClassSubHandler(Handler):
- @handler(u"subcmd: Print all the arguments, return nothing.")
+ @handler(u"subcmd: Print all the arguments, return nothing")
def subcmd(self, *args):
print 'class.subclass.subcmd:', args
class TestClass(Handler):
- @handler(u"cmd1: Print all the arguments, return nothing.")
+ @handler(u"cmd1: Print all the arguments, return nothing")
def cmd1(self, *args):
print 'class.cmd1:', args
- @handler(u"cmd2: Print all the arguments, return nothing.")
+ @handler(u"cmd2: Print all the arguments, return nothing")
def cmd2(self, *args):
print 'class.cmd2:', args
subclass = TestClassSubHandler()
- test_class = TestClass()
+ class RootHandler(Handler):
+ func = staticmethod(test_func)
+ inst = TestClass()
- d = Dispatcher(dict(
- func=test_func,
- inst=test_class,
- ))
+ d = Dispatcher(RootHandler())
d.dispatch(r'''func arg1 arg2 arg3 "fourth 'argument' with \", a\ttab and\n\\n"''')
print 'inst commands:', tuple(d.dispatch('inst commands'))
d.dispatch('inst subclass subcmd arg1 arg2 arg3 arg4 arg5')
try:
d.dispatch('')
- except CommandNotFoundError, e:
+ except CommandNotSpecifiedError, e:
print 'Not found:', e
try:
d.dispatch('sucutrule piquete culete')
print 'Not found:', e
try:
d.dispatch('inst cmd3 arg1 arg2 arg3')
- except CommandNotFoundError, e:
+ except CommandNotInHandlerError, e:
+ print 'Not found:', e
+ try:
+ d.dispatch('inst')
+ except CommandIsAHandlerError, e:
print 'Not found:', e
+ print
+ print
# Parser tests
p = parse_command('hello world')
import signal
import socket
+from pymin.dispatcher import handler
+from pymin import dispatcher
from pymin import eventloop
from pymin import serializer
class PyminDaemon(eventloop.EventLoop):
- r"""PyminDaemon(bind_addr, routes) -> PyminDaemon instance
+ r"""PyminDaemon(root, bind_addr) -> PyminDaemon instance
This class is well suited to run as a single process. It handles
signals for controlled termination (SIGINT and SIGTERM), as well as
a user signal to reload the configuration files (SIGUSR1).
- bind_addr - is a tuple of (ip, port) where to bind the UDP socket to.
+ root - the root handler. This is passed directly to the Dispatcher.
- routes - is a dictionary where the key is a command string and the value
- is the command handler. This is passed directly to the Dispatcher.
+ bind_addr - is a tuple of (ip, port) where to bind the UDP socket to.
Here is a simple usage example:
- >>> def test_handler(*args): print 'test:', args
- >>> PyminDaemon(('', 9999), dict(test=test_handler)).run()
+ >>> from pymin import dispatcher
+ >>> class Root(dispatcher.Handler):
+ @handler('Test command.')
+ def test(self, *args):
+ print 'test:', args
+ >>> PyminDaemon(Root(), ('', 9999)).run()
"""
- def __init__(self, routes=dict(), bind_addr=('', 9999)):
+ def __init__(self, root, bind_addr=('', 9999)):
r"""Initialize the PyminDaemon object.
See PyminDaemon class documentation for more info.
# Create EventLoop
eventloop.EventLoop.__init__(self, sock)
# Create Dispatcher
- self.dispatcher = Dispatcher(routes)
+ #TODO root.pymin = PyminHandler()
+ self.dispatcher = dispatcher.Dispatcher(root)
# Signal handling
def quit(signum, frame):
print "Shuting down ..."
r"handle() -> None :: Handle incoming events using the dispatcher."
(msg, addr) = self.file.recvfrom(65535)
try:
- result = self.dispatcher.dispatch(msg)
+ result = self.dispatcher.dispatch(unicode(msg, 'utf-8'))
if result is not None:
result = serializer.serialize(result)
response = u'OK '
response += u'0\n'
else:
response += u'%d\n%s' % (len(result), result)
- self.file.sendto(response, addr)
+ self.file.sendto(response.encode('utf-8'), addr)
def run(self):
r"run() -> None :: Run the event loop (shortcut to loop())"
if __name__ == '__main__':
- @handler(u"Print all the arguments, return nothing.")
- def test_handler(*args):
- print 'test:', args
-
- @handler(u"Echo the message passed as argument.")
- def echo_handler(message):
- print 'echo:', message
- return message
+ class Root(dispatcher.Handler):
+ @handler(u"Print all the arguments, return nothing.")
+ def test(self, *args):
+ print 'test:', args
+ @handler(u"Echo the message passed as argument.")
+ def echo(self, message):
+ print 'echo:', message
+ return message
- PyminDaemon(dict(test=test_handler, echo=echo_handler)).run()
+ PyminDaemon(Root()).run()
message - A descriptive error message.
"""
-
- def __init__(self, message):
- r"Initialize the Error object. See class documentation for more info."
- self.message = message
-
- def __str__(self):
- return self.message
+ pass
class HostError(Error, KeyError):
r"""
def __init__(self, hostname):
r"Initialize the object. See class documentation for more info."
- self.message = 'Host error: "%s"' % hostname
+ self.message = u'Host error: "%s"' % hostname
class HostAlreadyExistsError(HostError):
r"""
def __init__(self, hostname):
r"Initialize the object. See class documentation for more info."
- self.message = 'Host already exists: "%s"' % hostname
+ self.message = u'Host already exists: "%s"' % hostname
class HostNotFoundError(HostError):
r"""
def __init__(self, hostname):
r"Initialize the object. See class documentation for more info."
- self.message = 'Host not found: "%s"' % hostname
+ self.message = u'Host not found: "%s"' % hostname
class Host(Sequence):
hosts - A dictionary with string keys (hostnames) and Host instances values.
"""
+ handler_help = u"Manage DHCP hosts"
+
def __init__(self, hosts):
r"Initialize HostHandler object, see class documentation for details."
self.hosts = hosts
- @handler(u'Add a new host.')
+ @handler(u'Add a new host')
def add(self, name, ip, mac):
r"add(name, ip, mac) -> None :: Add a host to the hosts list."
if name in self.hosts:
raise HostAlreadyExistsError(name)
self.hosts[name] = Host(name, ip, mac)
- @handler(u'Update a host.')
+ @handler(u'Update a host')
def update(self, name, ip=None, mac=None):
r"update(name[, ip[, mac]]) -> None :: Update a host of the hosts list."
if not name in self.hosts:
if mac is not None:
self.hosts[name].mac = mac
- @handler(u'Delete a host.')
+ @handler(u'Delete a host')
def delete(self, name):
r"delete(name) -> None :: Delete a host of the hosts list."
if not name in self.hosts:
raise HostNotFoundError(name)
del self.hosts[name]
- @handler(u'Get information about a host.')
+ @handler(u'Get information about a host')
def get(self, name):
r"get(name) -> Host :: List all the information of a host."
if not name in self.hosts:
raise HostNotFoundError(name)
return self.hosts[name]
- @handler(u'List hosts.')
+ @handler(u'List hosts')
def list(self):
r"list() -> tuple :: List all the hostnames."
return self.hosts.keys()
- @handler(u'Get information about all hosts.')
+ @handler(u'Get information about all hosts')
def show(self):
r"show() -> list of Hosts :: List all the complete hosts information."
return self.hosts.values()
Both defaults to the current working directory.
"""
+ handler_help = u"Manage DHCP service"
+
_initd_name = 'dhcpd'
_persistent_attrs = ('params', 'hosts')
message - A descriptive error message.
"""
-
- def __init__(self, message):
- r"Initialize the Error object. See class documentation for more info."
- self.message = message
-
- def __str__(self):
- return self.message
+ pass
class ZoneError(Error, KeyError):
r"""
def __init__(self, zonename):
r"Initialize the object. See class documentation for more info."
- self.message = 'Zone error: "%s"' % zonename
+ self.message = u'Zone error: "%s"' % zonename
class ZoneNotFoundError(ZoneError):
r"""
def __init__(self, zonename):
r"Initialize the object. See class documentation for more info."
- self.message = 'zone not found: "%s"' % zonename
+ self.message = u'zone not found: "%s"' % zonename
class ZoneAlreadyExistsError(ZoneError):
r"""
def __init__(self, zonename):
r"Initialize the object. See class documentation for more info."
- self.message = 'Zone already exists: "%s"' % zonename
+ self.message = u'Zone already exists: "%s"' % zonename
class HostError(Error, KeyError):
r"""
def __init__(self, hostname):
r"Initialize the object. See class documentation for more info."
- self.message = 'Host error: "%s"' % hostname
+ self.message = u'Host error: "%s"' % hostname
class HostAlreadyExistsError(HostError):
r"""
def __init__(self, hostname):
r"Initialize the object. See class documentation for more info."
- self.message = 'Host already exists: "%s"' % hostname
+ self.message = u'Host already exists: "%s"' % hostname
class HostNotFoundError(HostError):
r"""
- HostNotFoundError(hostname) -> HostNotFoundError instance
+ HostNotFoundError(hostname) -> HostNotFoundError instance.
This exception is raised when trying to operate on a hostname that doesn't
exists.
def __init__(self, hostname):
r"Initialize the object. See class documentation for more info."
- self.message = 'Host not found: "%s"' % hostname
+ self.message = u'Host not found: "%s"' % hostname
class MailExchangeError(Error, KeyError):
r"""
- MailExchangeError(hostname) -> MailExchangeError instance
+ MailExchangeError(hostname) -> MailExchangeError instance.
This is the base exception for all mail exchange related errors.
"""
def __init__(self, mx):
r"Initialize the object. See class documentation for more info."
- self.message = 'Mail Exchange error: "%s"' % mx
+ self.message = u'Mail Exchange error: "%s"' % mx
class MailExchangeAlreadyExistsError(MailExchangeError):
r"""
- MailExchangeAlreadyExistsError(hostname) -> MailExchangeAlreadyExistsError instance
+ MailExchangeAlreadyExistsError(hostname) -> MailExchangeAlreadyExistsError.
This exception is raised when trying to add a mail exchange that already exists.
"""
def __init__(self, mx):
r"Initialize the object. See class documentation for more info."
- self.message = 'Mail Exchange already exists: "%s"' % mx
+ self.message = u'Mail Exchange already exists: "%s"' % mx
class MailExchangeNotFoundError(MailExchangeError):
r"""
- MailExchangeNotFoundError(hostname) -> MailExchangeNotFoundError instance
+ MailExchangeNotFoundError(hostname) -> MailExchangeNotFoundError instance.
- This exception is raised when trying to operate on a mail exchange that doesn't
- exists.
+ This exception is raised when trying to operate on a mail exchange that
+ doesn't exists.
"""
def __init__(self, mx):
class NameServerAlreadyExistsError(NameServerError):
r"""
- NameServerAlreadyExistsError(hostname) -> NameServerAlreadyExistsError instance
+ NameServerAlreadyExistsError(hostname) -> NameServerAlreadyExistsError.
- This exception is raised when trying to add a name server that already exists.
+ This exception is raised when trying to add a name server that already
+ exists.
"""
def __init__(self, ns):
class NameServerNotFoundError(NameServerError):
r"""
- NameServerNotFoundError(hostname) -> NameServerNotFoundError instance
+ NameServerNotFoundError(hostname) -> NameServerNotFoundError instance.
- This exception is raised when trying to operate on a name server that doesn't
- exists.
+ This exception is raised when trying to operate on a name server that
+ doesn't exists.
"""
def __init__(self, ns):
return (self.name, self.ip)
class HostHandler(Handler):
+
+ handler_help = u"Manage DNS hosts"
+
def __init__(self,zones):
self.zones = zones
class MailExchangeHandler(Handler):
+ handler_help = u"Manage DNS mail exchangers (MX)"
+
def __init__(self, zones):
self.zones = zones
class NameServerHandler(Handler):
+ handler_help = u"Manage DNS name servers (NS)"
+
def __init__(self, zones):
self.zones = zones
return (self.name, self.hosts, self.mxs, self.nss)
class ZoneHandler(Handler):
-
r"""ZoneHandler(zones) -> ZoneHandler instance :: Handle a list of zones.
This class is a helper for DnsHandler to do all the work related to zone
zones - A dictionary with string keys (zone name) and Zone instances values.
"""
+
+ handler_help = u"Manage DNS zones"
+
def __init__(self, zones):
self.zones = zones
Both defaults to the current working directory.
"""
+ handler_help = u"Manage DNS service"
+
_initd_name = 'bind'
_persistent_attrs = ('params', 'zones')
message - A descriptive error message.
"""
-
- def __init__(self, message):
- r"Initialize the Error object. See class documentation for more info."
- self.message = message
-
- def __str__(self):
- return self.message
+ pass
class RuleError(Error, KeyError):
r"""
def __init__(self, rule):
r"Initialize the object. See class documentation for more info."
- self.message = 'Rule error: "%s"' % rule
+ self.message = u'Rule error: "%s"' % rule
class RuleAlreadyExistsError(RuleError):
r"""
def __init__(self, rule):
r"Initialize the object. See class documentation for more info."
- self.message = 'Rule already exists: "%s"' % rule
+ self.message = u'Rule already exists: "%s"' % rule
class RuleNotFoundError(RuleError):
r"""
def __init__(self, rule):
r"Initialize the object. See class documentation for more info."
- self.message = 'Rule not found: "%s"' % rule
+ self.message = u'Rule not found: "%s"' % rule
class Rule(Sequence):
rules - A list of Rule objects.
"""
+ handler_help = u"Manage firewall rules"
+
def __init__(self, rules):
r"Initialize the object, see class documentation for details."
self.rules = rules
- @handler(u'Add a new rule.')
+ @handler(u'Add a new rule')
def add(self, *args, **kwargs):
r"add(rule) -> None :: Add a rule to the rules list (see Rule doc)."
rule = Rule(*args, **kwargs)
raise RuleAlreadyExistsError(rule)
self.rules.append(rule)
- @handler(u'Update a rule.')
+ @handler(u'Update a rule')
def update(self, index, *args, **kwargs):
r"update(index, rule) -> None :: Update a rule (see Rule doc)."
# TODO check if the modified rule is the same of an existing one
except IndexError:
raise RuleNotFoundError(index)
- @handler(u'Delete a rule.')
+ @handler(u'Delete a rule')
def delete(self, index):
r"delete(index) -> Rule :: Delete a rule from the list returning it."
index = int(index) # TODO validation
except IndexError:
raise RuleNotFoundError(index)
- @handler(u'Get information about a rule.')
+ @handler(u'Get information about a rule')
def get(self, index):
r"get(rule) -> Rule :: Get all the information about a rule."
index = int(index) # TODO validation
except IndexError:
raise RuleNotFoundError(index)
- @handler(u'Get information about all rules.')
+ @handler(u'Get information about all rules')
def show(self):
r"show() -> list of Rules :: List all the complete rules information."
return self.rules
Both defaults to the current working directory.
"""
+ handler_help = u"Manage firewall service"
+
_persistent_attrs = 'rules'
_restorable_defaults = dict(rules=list())
message - A descriptive error message.
"""
-
- def __init__(self, message):
- r"Initialize the Error object. See class documentation for more info."
- self.message = message
-
- def __str__(self):
- return self.message
+ pass
class DeviceError(Error):
def __init__(self, device):
- self.message = 'Device error : "%s"' % device
+ self.message = u'Device error : "%s"' % device
class DeviceNotFoundError(DeviceError):
def __init__(self, device):
- self.message = 'Device not found : "%s"' % device
+ self.message = u'Device not found : "%s"' % device
class AddressError(Error):
def __init__(self, addr):
- self.message = 'Address error : "%s"' % addr
+ self.message = u'Address error : "%s"' % addr
class AddressNotFoundError(AddressError):
def __init__(self, address):
- self.message = 'Address not found : "%s"' % address
+ self.message = u'Address not found : "%s"' % address
class AddressAlreadyExistsError(AddressError):
def __init__(self, address):
- self.message = 'Address already exists : "%s"' % address
+ self.message = u'Address already exists : "%s"' % address
class RouteError(Error):
def __init__(self, route):
- self.message = 'Route error : "%s"' % route
+ self.message = u'Route error : "%s"' % route
class RouteNotFoundError(RouteError):
def __init__(self, route):
- self.message = 'Route not found : "%s"' % route
+ self.message = u'Route not found : "%s"' % route
class RouteAlreadyExistsError(RouteError):
def __init__(self, route):
- self.message = 'Route already exists : "%s"' % route
+ self.message = u'Route already exists : "%s"' % route
class Route(Sequence):
class RouteHandler(Handler):
+ handler_help = u"Manage IP routes"
+
def __init__(self, devices):
self.devices = devices
class AddressHandler(Handler):
+ handler_help = u"Manage IP addresses"
+
def __init__(self, devices):
self.devices = devices
class DeviceHandler(Handler):
+ handler_help = u"Manage network devices"
+
def __init__(self, devices):
# FIXME remove templates to execute commands
from mako.template import Template
class IpHandler(Restorable, ConfigWriter, TransactionalHandler):
+ handler_help = u"Manage IP devices, addresses and routes"
+
_persistent_attrs = 'devices'
_restorable_defaults = dict(devices=get_devices())
message - A descriptive error message.
"""
-
- def __init__(self, message):
- r"Initialize the Error object. See class documentation for more info."
- self.message = message
-
- def __str__(self):
- return self.message
+ pass
class HostError(Error, KeyError):
r"""
def __init__(self, hostname):
r"Initialize the object. See class documentation for more info."
- self.message = 'Host error: "%s"' % hostname
+ self.message = u'Host error: "%s"' % hostname
class HostAlreadyExistsError(HostError):
r"""
def __init__(self, hostname):
r"Initialize the object. See class documentation for more info."
- self.message = 'Host already exists: "%s"' % hostname
+ self.message = u'Host already exists: "%s"' % hostname
class HostNotFoundError(HostError):
r"""
def __init__(self, hostname):
r"Initialize the object. See class documentation for more info."
- self.message = 'Host not found: "%s"' % hostname
+ self.message = u'Host not found: "%s"' % hostname
class Host(Sequence):
class HostHandler(Handler):
+ handler_help = u"Manage proxy hosts"
+
def __init__(self, hosts):
self.hosts = hosts
class ProxyHandler(Restorable, ConfigWriter, InitdHandler,
TransactionalHandler, ParametersHandler):
+ handler_help = u"Manage proxy service"
+
_initd_name = 'squid'
_persistent_attrs = ('params', 'hosts', 'users')
from pymin.pymindaemon import PyminDaemon
import config
-PyminDaemon(config.routes, config.bind_addr).run()
+PyminDaemon(config.Root(), config.bind_addr).run()