NAT Outside IP not modifyable after being assigned as Primary to NAT Inside Device/VM #5147

Closed
opened 2025-12-29 19:24:49 +01:00 by adam · 2 comments
Owner

Originally created by @moonrail on GitHub (Aug 5, 2021).

Originally assigned to: @jeremystretch on GitHub.

NetBox version

v2.11.10

Python version

3.9

Steps to Reproduce

  1. Create a VM firewall1 with Interface interface1
  2. Create a VM virtualmachine1 with Interface ens192
  3. Create 2 IPs: 111.111.111.2/28, 10.0.0.4/24
  4. Assign IP 111.111.111.2/28 to firewall1 interface1
  5. Assign IP 10.0.0.4/24 to virtualmachine1 ens192
  6. Modify IP 111.111.111.2/28 to be the NAT Outside of IP 10.0.0.4/24
  7. Modify VM virtualmachine1 to use NAT-IP 111.111.111.2/28 as Primary IPv4
  8. Try to modify IP 111.111.111.2/28

Expected Behavior

IP 111.111.111.2/28 can be modified

Observed Behavior

IP 111.111.111.2/28 can not be modified.

Both UI and API return 400 "IP address is primary for virtual machine xyz but not assigned to it!"

It can only be deleted without error.

NetBox API:
Screenshot_20210805_163834

NetBox UI:
Screenshot_20210805_163720

The issue is found here in the model of IPAddress, where only direct assignments without respecting NAT assignments are fetched:
ee8fd701ae/netbox/ipam/models/ip.py (L650)

Originally created by @moonrail on GitHub (Aug 5, 2021). Originally assigned to: @jeremystretch on GitHub. ### NetBox version v2.11.10 ### Python version 3.9 ### Steps to Reproduce 1. Create a VM **firewall1** with Interface **interface1** 2. Create a VM **virtualmachine1** with Interface **ens192** 3. Create 2 IPs: **111.111.111.2/28**, **10.0.0.4/24** 4. Assign IP **111.111.111.2/28** to **firewall1 interface1** 5. Assign IP **10.0.0.4/24** to **virtualmachine1 ens192** 6. Modify IP **111.111.111.2/28** to be the NAT Outside of IP **10.0.0.4/24** 7. Modify VM **virtualmachine1** to use NAT-IP **111.111.111.2/28** as Primary IPv4 8. Try to modify IP **111.111.111.2/28** ### Expected Behavior IP **111.111.111.2/28** can be modified ### Observed Behavior IP **111.111.111.2/28** can not be modified. Both UI and API return 400 "IP address is primary for virtual machine xyz but not assigned to it!" It can only be deleted without error. NetBox API: ![Screenshot_20210805_163834](https://user-images.githubusercontent.com/40096303/128369113-fe01bf5c-9880-49da-9274-f38c9383ce31.png) NetBox UI: ![Screenshot_20210805_163720](https://user-images.githubusercontent.com/40096303/128369117-127cc78e-b272-4cdf-84da-abb80b54597e.png) The issue is found here in the model of IPAddress, where only direct assignments without respecting NAT assignments are fetched: https://github.com/netbox-community/netbox/blob/ee8fd701ae2d86ad74ab2d88ead341a9974226ff/netbox/ipam/models/ip.py#L650
adam added the type: bugstatus: accepted labels 2025-12-29 19:24:49 +01:00
adam closed this issue 2025-12-29 19:24:49 +01:00
Author
Owner

@moonrail commented on GitHub (Aug 5, 2021):

By adding a second check, this can be solved, e.g.:

        # Check for primary IP assignment that doesn't match the (NAT) assigned device/VM
        if self.pk:
            device = Device.objects.filter(Q(primary_ip4=self) | Q(primary_ip6=self)).first()
            if device:
                if getattr(self.assigned_object, 'device', None) != device:
                    if not self.nat_inside or getattr(self.nat_inside.assigned_object, 'device', None) != device:
                        raise ValidationError({
                            'interface': f"IP address is primary for device {device} but not assigned to it!"
                        })
            vm = VirtualMachine.objects.filter(Q(primary_ip4=self) | Q(primary_ip6=self)).first()
            if vm:
                if getattr(self.assigned_object, 'virtual_machine', None) != vm:
                    if not self.nat_inside or getattr(self.nat_inside.assigned_object, 'virtual_machine', None) != vm:
                        raise ValidationError({
                            'vminterface': f"IP address is primary for virtual machine {vm} but not assigned to it!"
                        })

By changing to the code above in my dev-environment, any NAT-Assignments are accepted.

Does this work for you? Should I open a PR?

@moonrail commented on GitHub (Aug 5, 2021): By adding a second check, this can be solved, e.g.: ```python # Check for primary IP assignment that doesn't match the (NAT) assigned device/VM if self.pk: device = Device.objects.filter(Q(primary_ip4=self) | Q(primary_ip6=self)).first() if device: if getattr(self.assigned_object, 'device', None) != device: if not self.nat_inside or getattr(self.nat_inside.assigned_object, 'device', None) != device: raise ValidationError({ 'interface': f"IP address is primary for device {device} but not assigned to it!" }) vm = VirtualMachine.objects.filter(Q(primary_ip4=self) | Q(primary_ip6=self)).first() if vm: if getattr(self.assigned_object, 'virtual_machine', None) != vm: if not self.nat_inside or getattr(self.nat_inside.assigned_object, 'virtual_machine', None) != vm: raise ValidationError({ 'vminterface': f"IP address is primary for virtual machine {vm} but not assigned to it!" }) ``` By changing to the code above in my dev-environment, any NAT-Assignments are accepted. Does this work for you? Should I open a PR?
Author
Owner

@jeremystretch commented on GitHub (Aug 12, 2021):

@moonrail thanks for your contribution! That's pretty much it, but I also want to take this opportunity to clean up the code a bit. I should have a fix pushed shortly.

@jeremystretch commented on GitHub (Aug 12, 2021): @moonrail thanks for your contribution! That's pretty much it, but I also want to take this opportunity to clean up the code a bit. I should have a fix pushed shortly.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#5147