from pymin.seqtools import Sequence
from pymin.dispatcher import Handler, handler, HandlerError
from pymin.services.util import Restorable, ConfigWriter, ServiceHandler, \
- TransactionalHandler
+ TransactionalHandler, ListSubHandler
-__ALL__ = ('FirewallHandler', 'Error', 'RuleError', 'RuleAlreadyExistsError',
- 'RuleNotFoundError')
+__ALL__ = ('FirewallHandler', 'Error')
class Error(HandlerError):
r"""
"""
pass
-class RuleError(Error, KeyError):
- r"""
- RuleError(rule) -> RuleError instance.
-
- This is the base exception for all rule related errors.
- """
-
- def __init__(self, rule):
- r"Initialize the object. See class documentation for more info."
- self.message = u'Rule error: "%s"' % rule
-
-class RuleAlreadyExistsError(RuleError):
- r"""
- RuleAlreadyExistsError(rule) -> RuleAlreadyExistsError instance.
-
- This exception is raised when trying to add a rule that already exists.
- """
-
- def __init__(self, rule):
- r"Initialize the object. See class documentation for more info."
- self.message = u'Rule already exists: "%s"' % rule
-
-class RuleNotFoundError(RuleError):
- r"""
- RuleNotFoundError(rule) -> RuleNotFoundError instance.
-
- This exception is raised when trying to operate on a rule that doesn't
- exists.
- """
-
- def __init__(self, rule):
- r"Initialize the object. See class documentation for more info."
- self.message = u'Rule not found: "%s"' % rule
-
-
class Rule(Sequence):
r"""Rule(chain, target[, src[, dst[, ...]]]) -> Rule instance.
def __cmp__(self, other):
r"Compares two Rule objects."
- if self.chain == other.chain \
- and self.target == other.target \
- and self.src == other.src \
- and self.dst == other.dst \
- and self.protocol == other.protocol \
- and self.src_port == other.src_port \
- and self.dst_port == other.dst_port:
- return 0
- return cmp(id(self), id(other))
+ return cmp(self.as_tuple(), other.as_tuple())
def as_tuple(self):
r"Return a tuple representing the rule."
return (self.chain, self.target, self.src, self.dst, self.protocol,
- self.src_port)
+ self.src_port, self.dst_port)
-class RuleHandler(Handler):
- r"""RuleHandler(rules) -> RuleHandler instance :: Handle a list of rules.
+class RuleHandler(ListSubHandler):
+ r"""RuleHandler(parent) -> RuleHandler instance :: Handle a list of rules.
This class is a helper for FirewallHandler to do all the work related to rules
administration.
- rules - A list of Rule objects.
+ parent - The parent service handler.
"""
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')
- def add(self, *args, **kwargs):
- r"add(rule) -> None :: Add a rule to the rules list (see Rule doc)."
- rule = Rule(*args, **kwargs)
- if rule in self.rules:
- raise RuleAlreadyExistsError(rule)
- self.rules.append(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
- index = int(index) # TODO validation
- try:
- self.rules[index].update(*args, **kwargs)
- except IndexError:
- raise RuleNotFoundError(index)
-
- @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
- try:
- return self.rules.pop(index)
- except IndexError:
- raise RuleNotFoundError(index)
-
- @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
- try:
- return self.rules[index]
- except IndexError:
- raise RuleNotFoundError(index)
-
- @handler(u'Get information about all rules')
- def show(self):
- r"show() -> list of Rules :: List all the complete rules information."
- return self.rules
-
+ _list_subhandler_attr = 'rules'
+ _list_subhandler_class = Rule
class FirewallHandler(Restorable, ConfigWriter, ServiceHandler,
TransactionalHandler):
r"Initialize the object, see class documentation for details."
self._persistent_dir = pickle_dir
self._config_writer_cfg_dir = config_dir
- self._service_start = path.join(self._config_writer_cfg_dir,
- self._config_writer_files)
+ self._service_start = ('sh', path.join(self._config_writer_cfg_dir,
+ self._config_writer_files))
self._service_stop = ('iptables', '-t', 'filter', '-F')
self._service_restart = self._service_start
self._service_reload = self._service_start
self._config_build_templates()
self._restore()
- self.rule = RuleHandler(self.rules)
+ self.rule = RuleHandler(self)
def _get_config_vars(self, config_file):
return dict(rules=self.rules)