# 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
         interfaces", ... }
        :rtype: dict
        """
        self._connect()
        confs = {} # used by the threads to return the confs
        threads = []

        self.log = logger
        args = [(confs, hn, 'firelet') for hn in self._targets ]
        Forker(self._get_conf, args, logger=logger)

        # parse the configurations
        log.debug("Parsing configurations")
        for hostname in self._targets:
            if hostname not in confs:
                raise Exception("No configuration received from %s" % \
                    hostname)

            iptables_save, ip_addr_show = confs[hostname]
            if iptables_save is None:
                raise Exception("No configuration received from %s" % \
                    hostname)

            log.debug("iptables_save:" + repr(iptables_save))
            iptables_p = self.parse_iptables_save(iptables_save,
                hostname=hostname)
            #TODO: iptables-save can be very slow when a firewall cannot
            # resolve localhost - add a warning?
            #log.debug("iptables_p %s" % repr(iptables_p))
            ip_a_s_p = self.parse_ip_addr_show(ip_addr_show)

# 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

         interfaces", ... }
        :rtype: dict
        """
        self._connect()
        confs = {} # used by the threads to return the confs
        threads = []

        self.log = logger
        args = [(confs, hn, 'firelet') for hn in self._targets ]
        Forker(self._get_conf, args, logger=logger)

        # parse the configurations
        log.debug("Parsing configurations")
        for hostname in self._targets:
            if hostname not in confs:
                raise Exception("No configuration received from %s" % \
                    hostname)

            iptables_save, ip_addr_show = confs[hostname]
            if iptables_save is None:
                raise Exception("No configuration received from %s" % \
                    hostname)

            log.debug("iptables_save:" + repr(iptables_save))
            iptables_p = self.parse_iptables_save(iptables_save,
                hostname=hostname)
            #TODO: iptables-save can be very slow when a firewall cannot
            # resolve localhost - add a warning?
            #log.debug("iptables_p %s" % repr(iptables_p))
            ip_a_s_p = self.parse_ip_addr_show(ip_addr_show)

            d = Bunch(iptables=iptables_p, ip_a_s=ip_a_s_p)