Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

setting primary IP failes when IP assigments are removed and re-assigned #204

Open
veritas-sot opened this issue Jun 24, 2024 · 3 comments

Comments

@veritas-sot
Copy link

Environment:

nautobot 2.2.5
pynautobot: 2.2.0

Details:

When I remove all existing IP assignmets of an interface, then re-assign all IP addresses to the interface and set the primary IP of the device, the primary IP is NOT set. Using the rest API works well. This could be similar to issue 197!

The follwing code does not work, it deletes the primary IP of the device

# get device, interface and IP
device = nautobot.dcim.devices.get(name='lab.local')
interface = nautobot.dcim.interfaces.get(device_id=device.id, name='Loopback0')
ip_address = nautobot.ipam.ip_addresses.get(address='192.168.2.1')

# get list of assigments
id_list = nautobot.ipam.ip_address_to_interface.filter(interface=interface.id, ip_address=ip_address.id)

# remove assignments
for assignment in id_list:
    assignment.delete()

# re-assign
assigned = nautobot.ipam.ip_address_to_interface.create({'interface': interface.id, 'ip_address': ip_address.id} )

# save
save = device.save()
# set primary
success = device.primary_ip4 = ip_address
#save
device.save()

When I add the following line to the code

device = nautobot.dcim.devices.get(name='lab.local')

right before setting the primary IP, it works.

I was asked to open this issue (https://networktocode.slack.com/archives/C01NWPK6WHL/p1718816339526429)

@joewesch
Copy link
Contributor

Using the rest API works well

Can you provide the REST API calls that work for you?

@veritas-sot
Copy link
Author

sure. I have got a little "Layer" between my script and nautobot (authentication and some error handling, nothing more).

# delete assigmnets

for iface in interfaces:
    interface_id = iface.get('id')
    ip_addresses = []
    ip_to_interface = rest.get(url=f"api/ipam/ip-address-to-interface/?interface={interface_id}")
    if ip_to_interface.get('count') > 0:
        ip_to_interface_id = ip_to_interface.get('results')[0].get('id')
        ip_addresses.append(ip_to_interface.get('results')[0].get('ip_address').get('id'))
        response = rest.delete(url=f"api/ipam/ip-address-to-interface/{ip_to_interface_id}/")
        print(response.status_code)
        if response.status_code == 204:
            print(f"Removed assignment from Interface {interface_id}")
        else:
            print(f"Failed to remove assignment from Interface {interface_id}")
            print(response.content)

    # add assigmnents
    for ip in ip_addresses:
        data = {'interface': interface_id, 'ip_address': ip}
        response = rest.post(url="api/ipam/ip-address-to-interface/", json=data)
        if response.status_code == 201:
            print(f"Interface {interface_id} updated")
        else:
            print(f"Interface {interface_id} not update ({response.status_code})")
            print(response.content)

# get IP id
address = "192.168.0.1"
response = rest.get(url=f"api/ipam/ip-addresses/?address={address}", format="json")
if response.get('count') > 0:
    ip_id = response.get('results')[0].get('id')

# set primary IP address
data = {'id': device_id, 'primary_ip4': {'id': ip_id} }
response = rest.patch(url="api/dcim/devices/", json=[data])
if response.status_code == 200:
    print(f"Device {device_id} updated")
else:
    print(f"Device {device_id} not updated ({response.status_code})")
    print(response.content)


@joewesch
Copy link
Contributor

joewesch commented Jul 9, 2024

I apologize for the delay in getting back to this.

I was unable to reproduce this error via pynautobot using the demo site (which is currently on 2.2.7) with the following code:

from pynautobot import api
url = "https://demo.nautobot.com/"
token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
nautobot = api(url=url, token=token)

# get device, interface and IP
device = nautobot.dcim.devices.get(name='atl01-sdwan-02')
interface = nautobot.dcim.interfaces.get(device_id=device.id, name='Loopback0')
ip_address = nautobot.ipam.ip_addresses.get(address='192.0.2.1')

## REST OF YOUR ORIGINAL SNIPPET
....

When I remove all existing IP assignmets of an interface

Can you confirm your original code snippet is correct? Your snippet is only removing a single assignment since you are filtering the assignments by the interface and the IP ID's:

id_list = nautobot.ipam.ip_address_to_interface.filter(interface=interface.id, ip_address=ip_address.id)

Is this maybe a bug in your code or did you provide an incorrect snippet?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants