NetBox to hosts
Overview
Performing a traceroute is a very common task for network operations.
In this post I share a simple solution I implemented to make it easier to read the command output.
Problem
I have noticed many requests to the NetOps team for clarification of traceroute output. The Service Desk team does not understand the traceroute between sites on the client's network.
Solution
Being a big fan of NetBox I onboarded the client's network some time ago, most of the network prefixes and IP addresses are already in the database.
Leveraging the database of IPs and names, I created a simple script to collect all IP entries in Netbox that have a non-empty DNS field.
The result is used to compile the hosts file of the local machine so you can see the names and IPs in the traceroute.
Script
The script is a mix of Python and bash. First, a Python script reads all the IP addresses in NetBox that have a non-empty DNS value and writes the output to hosts.netbox.
Then the Python script is executed by a bash script that takes care of updating the local [hosts](https://en.wikipedia.org/wiki/Hosts_(file) file.
Bash
Let's start exporting NetBox IP, API and the name of the VRF:
1export NBURL=https://localhost/
2export NBAPI=01234567890123456789
3export NBVRF=NAME-OF-VRF
The bash script:
- lines 5 to 11 create a backup of the current hosts file, if not already exists
- line 14 executes the Python script to collect the IP/name pairs and saves them in hosts.netbox
- lines 17 to 28 merge the original *hosts.old file with hosts.netbox into hosts
1#!/bin/bash
2set -e
3
4# Check if hosts.old does not exist
5if [ ! -f /etc/hosts.old ]; then
6 # Copy hosts to hosts.old
7 sudo sh -c 'cp /etc/hosts /etc/hosts.old'
8 echo "hosts file has been copied to hosts.old"
9else
10 echo "hosts.old already exists"
11fi
12
13echo "running netbox import..."
14python3 getNetBoxIPnames.py
15echo "done"
16
17if [ -f /etc/hosts.old ]; then
18 if [ -f hosts.netbox ]; then
19 # Copy hosts to hosts.old
20 echo "merging to hosts..."
21 sudo sh -c 'cat hosts.netbox >> /etc/hosts'
22 echo "OK netbox hosts merged to hosts"
23 else
24 echo "FAIL hosts.netbox missing"
25 fi
26else
27 echo "FAIL hosts.old missing"
28fi
Python
Notice on line 17 the use of the REST api filter dns_name__empty=False.
The script getNetBoxIPnames.py requires pynetbox module.
1import pynetbox
2import urllib3
3import os
4urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
5# set env vars before executing the script
6netbox_url = os.environ.get('NBURL',"")
7api_token = os.environ.get('NBAPI',"")
8vrf_name = os.environ.get('NBVRF',"") # the name of the VRF in string
9if not (netbox_url and api_token and vrf_name):
10 raise Exception("missing NBURL/NBAPINBVRF env vars")
11nb = pynetbox.api(netbox_url, token=api_token)
12nb.http_session.verify = False
13f = open("hosts.netbox", "w")
14vrf = nb.ipam.vrfs.get(name=vrf_name)
15if vrf:
16 # Get all IP addresses in the VRF with a DNS name
17 ip_addresses = nb.ipam.ip_addresses.filter(vrf_id=vrf.id, dns_name__empty=False)
18 print(f"collected {len(ip_addresses)} ip/names from netbox")
19 for ip in ip_addresses:
20 f.write(f"{ip.address.split('/')[0]} {ip.dns_name}\n")
21else:
22 print(f"FAIL: VRF '{vrf_name}' not found")
23 f.close()
24 sys.exit(1)
25f.close()
Run it
Export the necessary data:
1export NBURL=https://localhost/
2export NBAPI=01234567890123456789
3export NBVRF=MY-WONDERFUL-VRF
Run the script with sudo, it needs permission to write the hosts file:
1./getNBnames.sh
Now run your favorite traceroute tool (mine is mtr) and enjoy the output (obfuscated).
1 mtr -b 9.9.9.9
2
3 Host
4 1. _gateway (10.x.x.129)
5 2. (waiting for reply)
6 3. it-dc1-aci-l3out (10.199.199.1)
7 4. it-dc1-wsw01-vlan199 (10.x.x.60)
8 5. it-dc1-fw-int-1-vdom-vpn-nat (10.x.x.251)
9 6. it-dc1-fw--vdom-frontend-p2p-to-vdom-vpn-nat (192.x.x.130)
10 7. it-dc1-sw-fe-2 (192.x.x.3)
11 8. ce-isp1-internet-rtr-2 (212.x.x.29)
12 9. pe-isp1-internet (.x.x.129)
1310. rtr1.mix-it.net (217.x.x.51)
1411. rtr2 (109.x.x.196)
1512. dns9.quad9.net (9.9.9.9)
Final notes
I recommend using explicit, long DNS names that include the host name and interface, sometimes with a short description to help ServiceDesk/NetOps teams.
If the DNS field is already used and must remain within defined standards, NetBox supports the use of custom fields.
DNS limits (according to RFC 1035:
- labels: 63 octets or less
- names: 255 octets or less
There is plenty of room for self-explaining entries.
Where's the code?
The code is available in GitHub. Enjoy!