I sort of struggled what to call this blog entry, but at the time, this is what I was trying to do. I was tasked with taking a list of network IP Addresses from router/switch config files and compare them to a different list of networks currently defined in an Infoblox Grid. All I needed was something that worked and that was timely since I didn't have lavish amounts of time.
The logical flow of my script would go something like this:
- fetch all Infoblox network objects
- store this list in a searchable collection
- iterate through my list of router networks and test against the collection
Basically, I wanted to know if the tested router network could be added OR not. And, if it couldn't, explain why. Was the network an exact match or did the network overlap an existing network in the Infoblox Grid?
I chose Python for the task and stumbled upon a wonderful IP Address module called netaddr that made this possible and easy! So, without further adieu, here's what I did.
Install Required Python Modules
Install python requests and netaddr. The requests module is used for performing RESTful API calls to the Infoblox Grid, while the netaddr module is used for parsing and/or manipulating IPv4 and IPv6 Addresses.
pip install netaddr pip install requests
NOTE: I used pip to install my modules, I suggest you use this method - it's easy. I'm not going to go into details about python module installations as it is beyond the scope of this blog post.
Fetch all Infoblox Grid Network objects
This can be accomplished with the python requests module as follows:
url = 'https://10.10.10.10/wapi/v1.7' username = 'admin' passwd = 'some_secret_password' with requests.Session() as s: s.auth = (username, passwd) s.verify = False r = s.get(url + '/network')
At this point, we should have a list of networks. If we don't, we may need to increase the number of objects that can be returned from our API call. This can be done by passing _max_results option with a larger value. The default is 1000 objects.
Store the list in a searchable collection
The next step is to put this list of network objects into a searchable collection. Enter netaddr python module! All you have to do is iterate through the collection of networks returned by the above API call, and store them into a netaddr.IPSet(). This can be done as follows:
# bloxnets is our collection of networks we'll search against bloxnets = IPSet() # iterate over the Infoblox collection of networks and store in IPSet() as IPNetwork() for obj in r.json(): bloxnets.add(IPNetwork(obj['network']))
Iterate through the network list and test against the collection
Ok, now we have a searchable collection. What's next? We're ready to start iterating through our list of networks we obtained from router and switch configs. We'll just assume for the purpose of this article that we stored those networks in a simple plain text file. So, here's the magic:
networks_file = 'router-networks.txt' fh = open(networks_file, 'r') for line in fh: network = IPNetwork(line) exists = network in bloxnets if exists is True: # it already exists or overlaps w/ network in the Infoblox Grid else: # it doesn't exist and can be safely added to the Infoblox Grid
How can we tell if the network we're checking is an exact match or overlaps with existing network(s)? We can modify the above code as follows:
networks_file = 'router-networks.txt' fh = open(networks_file, 'r') for line in fh: network = IPNetwork(line) exists = network in bloxnets if exists is True: # it already exists or overlaps w/ network in the Infoblox Grid myset = IPSet(IPNetwork(network)) overlap = myset & bloxnets if len(overlap) == 1: overlap = str(list(overlap.iter_cidrs)) if str(network) == str(overlap): # exact match else: # overlapping network.. list which network it collides with elsif len(overlap) > 1: # it overlaps/collides with many networks... list them out else: # it does not exist and can be safely added to the Infoblox Grid
There you have it. I was pretty amazed at how well this worked in a pinch. I hope this will help someone else that needs to perform such a task.