# Path: orangengine/utils.py
# def is_ipv4(value):
#     """
#     return true if value is any kind of ipv4 address.
#     address, network, or range
#     """
#     try:
#         if '-' in value:
#             # try a range
#             addr_range = value.split('-')
#             IPRange(addr_range[0], addr_range[1])
#         else:
#             IPNetwork(value)
#     except Exception:
#         return False
#     return True
# 
# def enum(*sequential, **named):
#     enums = dict(zip(sequential, range(len(sequential))), **named)
#     reverse = dict((value, key) for key, value in enums.iteritems())
#     enums['reverse_mapping'] = reverse
#     return type('Enum', (), enums)
# 
# class bidict(dict):
#     """Bidirectional dictionary for two-way lookups
# 
#     Thanks to @Basj
#     http://stackoverflow.com/questions/3318625/efficient-bidirectional-hash-table-in-python
# 
#     Extended to allow blind access to the inverse dict by way of __getitem__
#     """
#     def __init__(self, *args, **kwargs):
#         super(bidict, self).__init__(*args, **kwargs)
#         self.inverse = {}
#         for key, value in self.iteritems():
#             self.inverse.setdefault(value, []).append(key)
# 
#     def __setitem__(self, key, value):
#         super(bidict, self).__setitem__(key, value)
#         self.inverse.setdefault(value, []).append(key)
# 
#     def __delitem__(self, key):
#         self.inverse.setdefault(self[key], []).remove(key)
#         if self[key] in self.inverse and not self.inverse[self[key]]:
#             del self.inverse[self[key]]
#         super(bidict, self).__delitem__(key)
# 
#     def __getitem__(self, item):
#         try:
#             value = super(bidict, self).__getitem__(item)
#         except KeyError:
#             value = self.inverse[item]
#             if value and len(value) == 1:
#                 value = value[0]
#         return value
# 
# def flatten(l):
#     """Generate a flatten list of elements from an n-depth nested list
#     """
#     for el in l:
#         if isinstance(el, Iterable) and not isinstance(el, basestring) and not isinstance(el, tuple):
#             for sub in flatten(el):
#                 yield sub
#         else:
#             yield el
# 
# Path: orangengine/models/base/baseobject.py
# class BaseObject(object):
#     """Base class for all (most) objects. This class should almost never be
#     instantiated directly. It contains a few methods that are the available to
#     all sub classes.
#     """
# 
#     def serialize(self):
#         raise NotImplementedError()
# 
#     def to_json(self):
#         """Return a json dump of self returned from self.serialize()
#         """
#         return json.dumps(self.serialize())


from orangengine.utils import is_ipv4, enum, bidict, flatten
from orangengine.models.base import BaseObject
from collections import defaultdict
from netaddr import IPRange, IPNetwork
from terminaltables import AsciiTable
from functools import partial
        elif item == 'source_zones':
            return self.src_zones
        elif item == 'destination_zones':
            return self.dst_zones
        elif item == 'source_addresses':
            return set(flatten([a.value for a in self.src_addresses]))
        elif item == 'destination_addresses':
            return set(flatten([a.value for a in self.dst_addresses]))
        elif item == 'services':
            return set(flatten([s.value for s in self._services]))
        elif item == 'services_objects':
            return self._services

        else:
            raise AttributeError()

    @staticmethod
    def _in_network(value, p_value, exact_match=False):
        """

        """

        # 'any' address is an automatic match if we are exact
        if exact_match and 'any' in p_value:
            return True

        addresses = [IPRange(a.split('-')[0], a.split('-')[1]) if '-' in a else IPNetwork(a)
                     for a in value if is_ipv4(a)]
        fqdns = [a for a in value if not is_ipv4(a)]
        p_addresses = [IPRange(a.split('-')[0], a.split('-')[1]) if '-' in a else IPNetwork(a)

# Path: orangengine/utils.py
# def is_ipv4(value):
#     """
#     return true if value is any kind of ipv4 address.
#     address, network, or range
#     """
#     try:
#         if '-' in value:
#             # try a range
#             addr_range = value.split('-')
#             IPRange(addr_range[0], addr_range[1])
#         else:
#             IPNetwork(value)
#     except Exception:
#         return False
#     return True
# 
# def enum(*sequential, **named):
#     enums = dict(zip(sequential, range(len(sequential))), **named)
#     reverse = dict((value, key) for key, value in enums.iteritems())
#     enums['reverse_mapping'] = reverse
#     return type('Enum', (), enums)
# 
# class bidict(dict):
#     """Bidirectional dictionary for two-way lookups
# 
#     Thanks to @Basj
#     http://stackoverflow.com/questions/3318625/efficient-bidirectional-hash-table-in-python
# 
#     Extended to allow blind access to the inverse dict by way of __getitem__
#     """
#     def __init__(self, *args, **kwargs):
#         super(bidict, self).__init__(*args, **kwargs)
#         self.inverse = {}
#         for key, value in self.iteritems():
#             self.inverse.setdefault(value, []).append(key)
# 
#     def __setitem__(self, key, value):
#         super(bidict, self).__setitem__(key, value)
#         self.inverse.setdefault(value, []).append(key)
# 
#     def __delitem__(self, key):
#         self.inverse.setdefault(self[key], []).remove(key)
#         if self[key] in self.inverse and not self.inverse[self[key]]:
#             del self.inverse[self[key]]
#         super(bidict, self).__delitem__(key)
# 
#     def __getitem__(self, item):
#         try:
#             value = super(bidict, self).__getitem__(item)
#         except KeyError:
#             value = self.inverse[item]
#             if value and len(value) == 1:
#                 value = value[0]
#         return value
# 
# def flatten(l):
#     """Generate a flatten list of elements from an n-depth nested list
#     """
#     for el in l:
#         if isinstance(el, Iterable) and not isinstance(el, basestring) and not isinstance(el, tuple):
#             for sub in flatten(el):
#                 yield sub
#         else:
#             yield el
# 
# Path: orangengine/models/base/baseobject.py
# class BaseObject(object):
#     """Base class for all (most) objects. This class should almost never be
#     instantiated directly. It contains a few methods that are the available to
#     all sub classes.
#     """
# 
#     def serialize(self):
#         raise NotImplementedError()
# 
#     def to_json(self):
#         """Return a json dump of self returned from self.serialize()
#         """
#         return json.dumps(self.serialize())


# Path: orangengine/models/base/basepolicy.py
from orangengine.utils import is_ipv4, enum, bidict, flatten
from orangengine.models.base import BaseObject
from collections import defaultdict
from netaddr import IPRange, IPNetwork
from terminaltables import AsciiTable
from functools import partial

        elif item == 'source_zones':
            return self.src_zones
        elif item == 'destination_zones':
            return self.dst_zones
        elif item == 'source_addresses':
            return set(flatten([a.value for a in self.src_addresses]))
        elif item == 'destination_addresses':
            return set(flatten([a.value for a in self.dst_addresses]))
        elif item == 'services':
            return set(flatten([s.value for s in self._services]))
        elif item == 'services_objects':
            return self._services

        else:
            raise AttributeError()

    @staticmethod
    def _in_network(value, p_value, exact_match=False):
        """

        """

        # 'any' address is an automatic match if we are exact
        if exact_match and 'any' in p_value:
            return True

        addresses = [IPRange(a.split('-')[0], a.split('-')[1]) if '-' in a else IPNetwork(a)
                     for a in value if is_ipv4(a)]
        fqdns = [a for a in value if not is_ipv4(a)]
        p_addresses = [IPRange(a.split('-')[0], a.split('-')[1]) if '-' in a else IPNetwork(a)

                       for a in p_value if is_ipv4(a)]