# Path: firelet/flutils.py
# class Bunch(object):
#     """A dict that exposes its values as attributes."""
#     def __init__(self, **kw):
#         self.__dict__ = dict(kw)
# 
#     def __repr__(self):
#         return repr(self.__dict__)
# 
#     def __len__(self):
#         return len(self.__dict__)
# 
#     def __getitem__(self, name):
#         return self.__dict__.__getitem__(name)
# 
#     def __setitem__(self, name, value):
#         return self.__dict__.__setitem__(name, value)
# 
#     def __iter__(self):
#         return self.__dict__.__iter__()
# 
#     def keys(self):
#         """Get the instance attributes
# 
#         :rtype: list
#         """
#         return self.__dict__.keys()
# 
#     def _token(self):
#         """Generate a simple hash to detect changes in the bunch attributes
#         """
#         h = hashlib.md5()
#         [h.update(k + str(v)) for k, v in sorted(self.__dict__.iteritems())]
#         return h.hexdigest()[:8]
# 
#     def validate_token(self, token):
#         """Check if the given token matches the instance own token to ensure
#         that the instance attributes has not been modified.
#         The token is a hash of the instance's attributes.
# 
#         :param token: token
#         :type token: str
#         :returns: True or False
#         """
#         assert token == self._token(), \
#         "Unable to update: one or more items has been modified in the meantime."
# 
#     def attr_dict(self):
#         """Provide a copy of the internal dict, with a token"""
#         d = deepcopy(self.__dict__)
#         d['token'] = self._token()
#         return d
# 
#     def update(self, d):
#         """Set/update the internal dictionary"""
#         for k in self.__dict__:
#             self.__dict__[k] = d[k]


from datetime import datetime
from time import time
from threading import Thread
from .flutils import Bunch
import logging
import paramiko
        COMMIT
        # Completed on Sun Feb 20 15:17:57 2011
        """

        def _rules(x):
            """Extract rules, ignore comments and anything else"""
            return x.startswith(('-A PREROUTING', '-A POSTROUTING',
                '-A OUTPUT', '-A INPUT', '-A FORWARD'))

        r = ('-A PREROUTING', '-A POSTROUTING',
                '-A OUTPUT', '-A INPUT', '-A FORWARD')

        if isinstance(li, str):
            li = li.split('\n')
        try:
            block = li[li.index('*nat'):li.index('COMMIT')]
            nat = filter(_rules, block)
        except ValueError:
            nat = []

        try:
            filter_li = li[li.index('*filter'):]    # start from *filter
            block = filter_li[:filter_li.index('COMMIT')] # up to COMMIT
            f = filter(_rules, block)
        except ValueError:
            log.error("Unable to parse iptables-save output: missing '*filter'"
                " and/or 'COMMIT' on %s: %s" % (hostname, repr(li)))
            raise Exception("Unable to parse iptables-save output: missing "
                "'*filter' and/or 'COMMIT' in %r" % li)


# Path: firelet/flutils.py
# class Bunch(object):
#     """A dict that exposes its values as attributes."""
#     def __init__(self, **kw):
#         self.__dict__ = dict(kw)
# 
#     def __repr__(self):
#         return repr(self.__dict__)
# 
#     def __len__(self):
#         return len(self.__dict__)
# 
#     def __getitem__(self, name):
#         return self.__dict__.__getitem__(name)
# 
#     def __setitem__(self, name, value):
#         return self.__dict__.__setitem__(name, value)
# 
#     def __iter__(self):
#         return self.__dict__.__iter__()
# 
#     def keys(self):
#         """Get the instance attributes
# 
#         :rtype: list
#         """
#         return self.__dict__.keys()
# 
#     def _token(self):
#         """Generate a simple hash to detect changes in the bunch attributes
#         """
#         h = hashlib.md5()
#         [h.update(k + str(v)) for k, v in sorted(self.__dict__.iteritems())]
#         return h.hexdigest()[:8]
# 
#     def validate_token(self, token):
#         """Check if the given token matches the instance own token to ensure
#         that the instance attributes has not been modified.
#         The token is a hash of the instance's attributes.
# 
#         :param token: token
#         :type token: str
#         :returns: True or False
#         """
#         assert token == self._token(), \
#         "Unable to update: one or more items has been modified in the meantime."
# 
#     def attr_dict(self):
#         """Provide a copy of the internal dict, with a token"""
#         d = deepcopy(self.__dict__)
#         d['token'] = self._token()
#         return d
# 
#     def update(self, d):
#         """Set/update the internal dictionary"""
#         for k in self.__dict__:
#             self.__dict__[k] = d[k]


# Path: firelet/flssh.py
from datetime import datetime
from time import time
from threading import Thread
from .flutils import Bunch
import logging
import paramiko

        COMMIT
        # Completed on Sun Feb 20 15:17:57 2011
        """

        def _rules(x):
            """Extract rules, ignore comments and anything else"""
            return x.startswith(('-A PREROUTING', '-A POSTROUTING',
                '-A OUTPUT', '-A INPUT', '-A FORWARD'))

        r = ('-A PREROUTING', '-A POSTROUTING',
                '-A OUTPUT', '-A INPUT', '-A FORWARD')

        if isinstance(li, str):
            li = li.split('\n')
        try:
            block = li[li.index('*nat'):li.index('COMMIT')]
            nat = filter(_rules, block)
        except ValueError:
            nat = []

        try:
            filter_li = li[li.index('*filter'):]    # start from *filter
            block = filter_li[:filter_li.index('COMMIT')] # up to COMMIT
            f = filter(_rules, block)
        except ValueError:
            log.error("Unable to parse iptables-save output: missing '*filter'"
                " and/or 'COMMIT' on %s: %s" % (hostname, repr(li)))
            raise Exception("Unable to parse iptables-save output: missing "
                "'*filter' and/or 'COMMIT' in %r" % li)


        return Bunch(nat=nat, filter=f)