summaryrefslogtreecommitdiff
path: root/netaddr/contrib/subnet_splitter.py
diff options
context:
space:
mode:
Diffstat (limited to 'netaddr/contrib/subnet_splitter.py')
-rw-r--r--netaddr/contrib/subnet_splitter.py41
1 files changed, 41 insertions, 0 deletions
diff --git a/netaddr/contrib/subnet_splitter.py b/netaddr/contrib/subnet_splitter.py
new file mode 100644
index 0000000..2e39d41
--- /dev/null
+++ b/netaddr/contrib/subnet_splitter.py
@@ -0,0 +1,41 @@
+from netaddr.ip import IPNetwork, cidr_exclude, cidr_merge
+
+
+class SubnetSplitter(object):
+ """
+ A handy utility class that takes a single (large) subnet and allows
+ smaller subnet within its range to be extracted by CIDR prefix. Any
+ leaving address space is available for subsequent extractions until
+ all space is exhausted.
+ """
+ def __init__(self, base_cidr):
+ """
+ Constructor.
+
+ :param base_cidr: an IPv4 or IPv6 address with a CIDR prefix.
+ (see IPNetwork.__init__ for full details).
+ """
+ self._subnets = set([IPNetwork(base_cidr)])
+
+ def extract_subnet(self, prefix, count=None):
+ """Extract 1 or more subnets of size specified by CIDR prefix."""
+ for cidr in self.available_subnets():
+ subnets = list(cidr.subnet(prefix, count=count))
+ if not subnets:
+ continue
+ self.remove_subnet(cidr)
+ self._subnets = self._subnets.union(
+ set(
+ cidr_exclude(cidr, cidr_merge(subnets)[0])
+ )
+ )
+ return subnets
+ return []
+
+ def available_subnets(self):
+ """Returns a list of the currently available subnets."""
+ return sorted(self._subnets, key=lambda x: x.prefixlen, reverse=True)
+
+ def remove_subnet(self, ip_network):
+ """Remove a specified IPNetwork from available address space."""
+ self._subnets.remove(ip_network)