Calling a function in the second loop returns unexpected value

Question:

I’m mapping my switches to a tool called Netbox which is a CMDB tool.

I have a list of switches for example: [US-switch01, US-switch02]
If those devices don’t exist in Netbox, I would like to create that device. Here is the script right now:

import pynetbox
nb = pynetbox.api(
    'http://netbox.domain.com',
    token='token'
)

devices = nb.dcim.devices.all() # An object of all devices in my Netbox instance
sites = nb.dcim.sites.all() # An object of all sites in my Netbox instance (EU, US for example)

def getSiteID(site):
    for s in sites:
        if s.name.upper() == site.upper():
            return s.id # Returns the ID of the site given to is. For example US site ID is 1. EU site ID is 2.

def getDeviceID(device):
    for d in devices:
        if d.name.upper() == device.upper():
            return d.id

if __name__ == "__main__":
    switch_list = ["US-switch01", "US-switch02"]
    for switch in switch_list:
        print(f"Working on {switch}")
        if getDeviceID(switch) is None:
            siteName = switch.split('-')[0]
            print(siteName, getSiteID(siteName))

When I run my script, I first test what it would find:

print(siteName, getSite(siteName))

So the above print should return siteName and the Side ID, which is what getSite() is doing.
The expected output is:

Working on US-switch01
US 1 #site name is US and the ID in netbox is 1
Working on US-switch02
EU 2 #site name is US and the ID in netbox is 1

For some reason, the output is this:

Working on US-switch01
US 1
Working on US-switch02
US None

Why do I get None as the returned value on the 2nd loop?

The weird part

If I use this list: [US-switch01, EU-switch01] then the script works:

Working on US-switch01
US 1
Working on EU-switch02
EU 2

So the issue seems to be when there are 2 consecutive switches with the same site. Why? What am I missing here?

Asked By: Daniel

||

Answers:

I suspect that you get generators (not lists) from the method .all(). So in the second call the generator has remembered the position from the first call. Try to make lists of the results of .all().

devices = list(nb.dcim.devices.all())
sites = list(nb.dcim.sites.all())

This should solve the problem.

Answered By: Donat
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.