71 lines
1.9 KiB
Python
71 lines
1.9 KiB
Python
# -*- 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)
|