Skip to content

Instantly share code, notes, and snippets.

@p-sherratt
Created August 4, 2022 09:14
Show Gist options
  • Save p-sherratt/e0fd4d34a946c186995a27810cfed286 to your computer and use it in GitHub Desktop.
Save p-sherratt/e0fd4d34a946c186995a27810cfed286 to your computer and use it in GitHub Desktop.
Produce a "CIDR report" from Netbox
#!/usr/bin/env python3
# quick hacky script to produce a "CIDR report" of your global address space from Netbox
# this is released to the public domain, free of copyright and licensing.
# by Paul Sherratt
import urllib3
urllib3.disable_warnings()
import requests
import pynetbox
from netaddr import IPNetwork, IPAddress, IPSet
NETBOX_URL='https://netbox'
NETBOX_TOKEN=''
session = requests.Session()
session.verify = False
nb = pynetbox.api(NETBOX_URL, NETBOX_TOKEN)
nb.http_session = session
aggregates = nb.ipam.aggregates.filter(family=4, rir__n='private')
aggregates = {agg.prefix: {} for agg in aggregates}
roles = {}
total_addresses = 0
for aggregate, data in aggregates.items():
prefix, prefix_length = aggregate.split('/')
prefix_length = int(prefix_length)
data['addresses'] = 2**(32-prefix_length)
data['prefixes'] = list(nb.ipam.prefixes.filter(family=4, within=aggregate, status__n='container'))
total_addresses += data['addresses']
for aggregate, data in aggregates.items():
prefixes = {IPNetwork(p.prefix): str(p.role) for p in data['prefixes']}
data['ipset'] = IPSet()
last_network = 0
for prefix, role in prefixes.items():
if prefix.network == last_network: # ignore duplicate entries
continue
last_network = prefix.network
data['ipset'].add(prefix)
if role not in roles:
roles[role] = 0
roles[role] += 2**(32-prefix.prefixlen)
data['gaps'] = IPSet(IPNetwork(aggregate)) - data['ipset']
def cidr_report(prefix_length):
count = 0
for data in aggregates.values():
for network in data['gaps'].iter_cidrs():
if network.prefixlen <= prefix_length:
count += 2**(prefix_length-network.prefixlen)
return count
def print_report():
print("Addresses Total:", total_addresses)
print("Addresses Allocated:", sum(roles.values()))
print("Addresses Free:", total_addresses - sum(roles.values()))
print()
print("Addresses Allocated Per Role:")
for role in sorted(roles.keys()):
print(f" {role}: {roles[role]}")
print()
print("CIDR Report - Free Address Blocks:")
for x in range(23,33):
print(f" /{x}: {cidr_report(x)}")
print_report()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment