Skip to content

Instantly share code, notes, and snippets.

@awfki
Last active November 16, 2023 22:19
Show Gist options
  • Save awfki/9884c85fa7cc9699de4001662c63646c to your computer and use it in GitHub Desktop.
Save awfki/9884c85fa7cc9699de4001662c63646c to your computer and use it in GitHub Desktop.
pynetbox examples

pynetbox examples

Long time network engineer, did some perl a long time ago and am liking python pretty well but the pynetbox documentation is badly lacking IMO. If I were a python wizard I'm sure it would all be obvious but I'm not and it's really frustrating that more example weren't provided.

Many of the following examples were cadged from various places on the interwebs and HAVE NOT BEEN TESTED.

Prereqs

import pynetbox
NETBOX = 'https://netbox.fq.dn/'
nb = pynetbox.api(NETBOX, get_token('nb'))

get_token() is function that fetches the token from a hidden file in the home dir (~) that's named token_nb. I've added it here as a separate file.

getting things

get all the things

response = nb.dcim.devices.all()
response = nb.ipam.prefixes.all()
response = nb.ipam.ip_addresses.all()
response = nb.ipam.vlans.get(vlanid)
response = nb.dcim.devices.get(serial=tgt_sn)

get list of things that match your query

response_list = nb.dcim.devices.filter(query)
response_list = nb.ipam.prefixes.filter(query)
response_list = nb.ipam.vlans.filter(query)
response_list = nb.tenancy.tenants.filter(query)
response_list = nb.dcim.interfaces.filter(device='DEV_NAME')

deleting things

response = nb.ipam.ip_addresses.get(name=line)
response.delete

renaming things

response = nb.dcim.devices.get(name=old_name)
response.name = new_name
response.save()

adding interface connection

int_a = nb.dcim.interfaces.get(name='xe-4/0/16', device='BLAHSWITCH')
int_b = nb.dcim.interfaces.get(name='eth3', device='BLAHHOST')
nb.dcim.interface_connections.create(
     interface_a=int_a.id,
     interface_b=int_b.id
)

creating things

create a device

netbox.dcim.devices.create(
  name='test',
  device_role=1,
)

create an interface (verified!)

response = nb.dcim.interfaces.create(
    device=721,
    name="Eth1/3",
    form_factor=1200,
    enabled=True,
    )

response is...

{ 'id': 13131, 
  'device': {'id': 721, 'url': 'https://netbox/api/dcim/devices/721/', 
    'name': 'TEST01', 'display_name': 'TEST01'
  }, 
  'name': 'Eth1/3', 
  'form_factor': {'value': 1200, 'label': 'SFP+ (10GE)'}, 
  'enabled': True, 'lag': None, 'mtu': None, 'mac_address': None, 
  'mgmt_only': False, 'description': '', 'is_connected': False, 
  'interface_connection': None, 'circuit_termination': None, 
  'mode': None, 'untagged_vlan': None, 'tagged_vlans': [], 'tags': []
}
# works on *nix systems, Windows users are on their own.
# note: the token_nb file contains the token string and NOTHING else.
import os
def get_token(TARGET):
"""Read token from ~/.token_TARGET."""
"""You should chmod 600 ~/.token_* so that only the owner (and root) can read them."""
token_file = '{}/.token_{}'.format(os.environ['HOME'], TARGET)
try:
with open(token_file) as f:
token = f.read().splitlines()
except IOError as e:
print(("{} config file is missing or cannot be read.".format(TARGET)))
token = None
return str(token[0]).strip()
# -----------------------
# this is another version that includes the is_insecure() function to check that the file is chmod 600.
import os
import stat
def is_insecure(filepath):
"""Check if file is accessible by group or other."""
st = os.stat(filepath)
if st.st_mode & stat.S_IRGRP:
return True
if st.st_mode & stat.S_IWGRP:
return True
if st.st_mode & stat.S_IXGRP:
return True
if st.st_mode & stat.S_IROTH:
return True
if st.st_mode & stat.S_IWOTH:
return True
if st.st_mode & stat.S_IXOTH:
return True
return False
def get_token(TARGET):
"""Read token from ~/.token_TARGET."""
token_file = '{}/.token_{}'.format(os.environ['HOME'], TARGET)
if is_insecure(token_file):
print('Token file is insecure, please chmod 600 {}'.format(token_file))
print('EXITING')
sys.exit(1)
try:
with open(token_file) as f:
token = f.read().splitlines()
token = token[0].strip()
except IOError as e:
print("{} config file is missing or cannot be read.".format(TARGET))
token = None
return token
@jblalock1980
Copy link

Thanks a ton for these examples. I also had a tough time finding decent documentation for pynetbox and yours were very helpful. I'm running Netbox 2.94 & pynetbox 5.1.0. I had to add a couple lines to what you list in the prereqs section above to connect using https with a local untrusted cert. Hopefully this will help if others have the same issue.

import requests
import pynetbox
from requests.packages.urllib3.exceptions import InsecureRequestWarning
session = requests.Session()
session.verify = False
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
NETBOX = 'https://netbox.fq.dn/'
nb = pynetbox.api(NETBOX, get_token('nb'))
nb.http_session = session

@senikamake
Copy link

thanks for the example. but is there any command for update interface? please advise

@tars01
Copy link

tars01 commented Jan 26, 2021

This is great, I had the same problem with no examples in the documentation.

Thanks

@nomad-cyanide
Copy link

Thanks for example. Keep em coming.
Currently I am having problems extracting information about vlans using pynetbox. Not a python-wiz by any standards, btw:
After the initial setup of connection to Netbox I try this, which works fine:

vlan1 = nb.ipam.vlans.filter(group='groupname',vid='555')
print (vlan1)
[GroupNamepg555Vlan]

I would like to get more than the vlan name, but cannot figure out how to display other info than the name, because eventually I want to extract all vlans for 1 tenant and deploy those on the switching-infrastructure, but every attempt I make ends in:

AttributeError: 'list' object has no attribute 'vid'

Like

print (vlan1.vid)
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'list' object has no attribute 'vid'

Even though vid should be an endpoint if I read and understand the API correctly (which I clearly don't). Can someone help me figure it out?

@tuxillo
Copy link

tuxillo commented Jun 23, 2021

Thanks for the examples.

For deleting things you actually have to call the delete() method.

@agomerz
Copy link

agomerz commented Oct 12, 2021

This gist saved my life

@allenrobel
Copy link

vlan1 = nb.ipam.vlans.filter(group='groupname',vid='555') print (vlan1) [GroupNamepg555Vlan]
...
AttributeError: 'list' object has no attribute 'vid'

Hi nomad-cyanide,

filter() returns a list of records (potentially a list of one record), so you need to iterate that list, like so:

vlans = nb.ipam.vlans.filter(group='groupname',vid='555')
for vlan in vlans:
   print(dict(vlan)) # prints all the info in the vlan record
   print(vlan.vid) # prints just the vlan id

If you want to get just a single record, you need to use get() instead of filter(). But, with get(), you'll need to ensure that the arguments are sufficient to uniquely identify one record, or you'll get an error. So, assuming your arguments above are enough to uniquely id one vlan, you could do:

try:
    vlan = nb.ipam.vlans.get(group='groupname',vid='555')
    print(vlan.vid)
except Exception as e:
    print('Exiting. Unable to retrieve vlan. Error was {}'.format(e))
    exit(1)

@daniel-zook
Copy link

daniel-zook commented Nov 22, 2022

Figured out how to iterate through interfaces on a given device and update some fields on the interfaces. In case anyone else was curious, use the NetBox API docs to know what to use for object properties. (/api/docs/ on your NetBox)

Here is an example. (Sorry it's ugly. I included a screenshot. Not sure how to put formatted code in here. The "code" button in the comment toolbar isn't working as expected when I preview.)

`import pynetbox

nb = pynetbox.api(
'http://ansible.emu.edu:8000',
token='0123456789abcdef0123456789abcdef01234567'
)

if name == 'main':
# print(*nb.dcim.devices.all(), sep="\n")
# This is a recordset: https://pynetbox.readthedocs.io/en/latest/response.html#pynetbox.core.response.RecordSet
core_interfaces = nb.dcim.interfaces.filter('irb', device='core-0')
# print(*core_interfaces, sep="\n")
for interface in core_interfaces:
name = interface.name
interface_id = str(interface.id)
unit = name[4:]
if int(unit) < 319:
continue
int_obj = nb.dcim.interfaces.get(interface_id)
# print(unit + " (" + interface_id + ")")
# print(int_obj.name)
vlan = nb.ipam.vlans.get(vid=unit)
if vlan is None:
continue
result = int_obj.update({
"mode": "access",
"untagged_vlan": vlan.id
})
print(int_obj.name + " - " + vlan.name + " - id: " + str(vlan.id) + " - result: " + str(result))
`

2022-11-22 16_40_03-set_core_irb_interface_vlans – example py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment