1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Fixes #5038: Fix validation of primary IPs assigned to virtual machines

This commit is contained in:
Jeremy Stretch
2020-08-24 09:41:04 -04:00
parent 3522eafd2c
commit 6e28490b84
4 changed files with 26 additions and 17 deletions

View File

@ -1,5 +1,13 @@
# NetBox v2.9
## v2.9.2 (FUTURE)
### Bug Fixes
* [#5038](https://github.com/netbox-community/netbox/issues/5038) - Fix validation of primary IPs assigned to virtual machines
---
## v2.9.1 (2020-08-22)
### Enhancements

View File

@ -1811,7 +1811,7 @@ class DeviceForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
nat_inside__assigned_object_id__in=interface_ids
).prefetch_related('assigned_object')
if nat_ips:
ip_list = [(ip.id, f'{ip.address} ({ip.assigned_object})') for ip in nat_ips]
ip_list = [(ip.id, f'{ip.address} (NAT)') for ip in nat_ips]
ip_choices.append(('NAT IPs', ip_list))
self.fields['primary_ip{}'.format(family)].choices = ip_choices

View File

@ -1,4 +1,5 @@
from django import forms
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from dcim.choices import InterfaceModeChoices
@ -325,28 +326,28 @@ class VirtualMachineForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
# Compile list of choices for primary IPv4 and IPv6 addresses
for family in [4, 6]:
ip_choices = [(None, '---------')]
# Gather PKs of all interfaces belonging to this VM
interface_ids = self.instance.interfaces.values_list('pk', flat=True)
# Collect interface IPs
interface_ips = IPAddress.objects.prefetch_related('interface').filter(
interface_ips = IPAddress.objects.filter(
address__family=family,
vminterface__in=self.instance.interfaces.values_list('id', flat=True)
assigned_object_type=ContentType.objects.get_for_model(VMInterface),
assigned_object_id__in=interface_ids
)
if interface_ips:
ip_choices.append(
('Interface IPs', [
(ip.id, '{} ({})'.format(ip.address, ip.interface)) for ip in interface_ips
])
)
ip_list = [(ip.id, f'{ip.address} ({ip.assigned_object})') for ip in interface_ips]
ip_choices.append(('Interface IPs', ip_list))
# Collect NAT IPs
nat_ips = IPAddress.objects.prefetch_related('nat_inside').filter(
address__family=family,
nat_inside__vminterface__in=self.instance.interfaces.values_list('id', flat=True)
nat_inside__assigned_object_type=ContentType.objects.get_for_model(VMInterface),
nat_inside__assigned_object_id__in=interface_ids
)
if nat_ips:
ip_choices.append(
('NAT IPs', [
(ip.id, '{} ({})'.format(ip.address, ip.nat_inside.address)) for ip in nat_ips
])
)
ip_list = [(ip.id, f'{ip.address} (NAT)') for ip in nat_ips]
ip_choices.append(('NAT IPs', ip_list))
self.fields['primary_ip{}'.format(family)].choices = ip_choices
else:

View File

@ -335,13 +335,13 @@ class VirtualMachine(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
for field in ['primary_ip4', 'primary_ip6']:
ip = getattr(self, field)
if ip is not None:
if ip.interface in interfaces:
if ip.assigned_object in interfaces:
pass
elif self.primary_ip4.nat_inside is not None and self.primary_ip4.nat_inside.interface in interfaces:
elif ip.nat_inside is not None and ip.nat_inside.assigned_object in interfaces:
pass
else:
raise ValidationError({
field: "The specified IP address ({}) is not assigned to this VM.".format(ip),
field: f"The specified IP address ({ip}) is not assigned to this VM.",
})
def to_csv(self):