1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
|
# -*- coding: utf-8 -*-
from collections.abc import Container
import ipaddress
import itertools
class InternalIPS(Container):
"""
InternalIPS allows to specify CIDRs for INTERNAL_IPS.
It takes an iterable of ip addresses or ranges.
Inspiration taken from netaddr.IPSet, please use it if you can since
it support more advanced features like optimizing ranges and lookups.
"""
__slots__ = ["_cidrs"]
def __init__(self, iterable, sort_by_size=False):
"""
Constructor.
:param iterable: (optional) an iterable containing IP addresses and
subnets.
:param sort_by_size: sorts internal list according to size of ip
ranges, largest first.
"""
self._cidrs = []
for address in iterable:
self._cidrs.append(ipaddress.ip_network(address))
if sort_by_size:
self._cidrs = sorted(self._cidrs)
def __contains__(self, address):
"""
:param ip: An IP address or subnet.
:return: ``True`` if IP address or subnet is a member of this InternalIPS set.
"""
address = ipaddress.ip_address(address)
for cidr in self._cidrs:
if address in cidr:
return True
return False
def __hash__(self):
"""
Raises ``TypeError`` if this method is called.
"""
raise TypeError("InternalIPS containers are unhashable!")
def __len__(self):
"""
:return: the cardinality of this InternalIPS set.
"""
return sum(cidr.num_addresses for cidr in self._cidrs)
def __iter__(self):
"""
:return: an iterator over the IP addresses within this IP set.
"""
return itertools.chain(*self._cidrs)
def iter_cidrs(self):
"""
:return: an iterator over individual IP subnets within this IP set.
"""
return sorted(self._cidrs)
|