Skip to content

Instantly share code, notes, and snippets.

@pmeulen
Last active November 3, 2018 21:58
Show Gist options
  • Save pmeulen/476208492a9938f408459747247c9902 to your computer and use it in GitHub Desktop.
Save pmeulen/476208492a9938f408459747247c9902 to your computer and use it in GitHub Desktop.
Python script to represent a list of CIDR network ranges in the smallest number of CIDR subnets. Subnets can be added and substracted.
#!/usr/bin/env python
import argparse, sys
from netaddr import IPNetwork, IPSet
class IPNetworkArg:
def __init__(self, network):
network.strip()
self.add = True
if network[0] == '-':
self.network = IPNetwork(network[1:])
self.add = False # I.e remove
elif network[0] == '+':
self.network = IPNetwork(network[1:])
else:
self.network = IPNetwork(network)
def __str__(self):
return ("+" if self.add else "-") + self.network.__str__()
def __repr__(self):
return "IPNetworkArg(\"" + self.__str__() + "\")"
parser = argparse.ArgumentParser(
prefix_chars='/',
fromfile_prefix_chars='@',
description='Represent a list of CIDR network ranges in the smallest number of CIDR subnets. The subnets are added to and substracted from the final range in the order they are specified on the command line.'
)
parser.add_argument(
dest='IPNetwork',
type=IPNetworkArg,
nargs='+',
help='A list of IP Addresses or IP networks in CIDR format (e.g. "192.168.0.0/24"). To substract a range, prefix it with "-" (e.g. "-192.168.0.3"). To load a list from file use "@filename".',
)
if len(sys.argv[1:])==0:
parser.print_help()
parser.exit()
vars = parser.parse_args()
ip_network_list=vars.IPNetwork
merged_list=IPSet()
for network in ip_network_list:
if network.add:
merged_list.add(network.network)
else:
merged_list.remove(network.network)
for cidr in merged_list.iter_cidrs():
print cidr
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment