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

Fixed #1500: Allow assigning IP addresses to virtual machines during CSV bulk import

This commit is contained in:
Jeremy Stretch
2017-09-18 13:30:20 -04:00
parent 9927ce14d3
commit 512a3bf09a
2 changed files with 49 additions and 15 deletions

View File

@ -13,6 +13,7 @@ from utilities.forms import (
ExpandableIPAddressField, FilterChoiceField, FlexibleModelChoiceField, Livesearch, ReturnURLForm, SlugField, ExpandableIPAddressField, FilterChoiceField, FlexibleModelChoiceField, Livesearch, ReturnURLForm, SlugField,
add_blank_choice, add_blank_choice,
) )
from virtualization.models import VirtualMachine
from .models import ( from .models import (
Aggregate, IPAddress, IPADDRESS_ROLE_CHOICES, IPADDRESS_STATUS_CHOICES, Prefix, PREFIX_STATUS_CHOICES, RIR, Role, Aggregate, IPAddress, IPADDRESS_ROLE_CHOICES, IPADDRESS_STATUS_CHOICES, Prefix, PREFIX_STATUS_CHOICES, RIR, Role,
Service, VLAN, VLANGroup, VLAN_STATUS_CHOICES, VRF, Service, VLAN, VLANGroup, VLAN_STATUS_CHOICES, VRF,
@ -566,6 +567,15 @@ class IPAddressCSVForm(forms.ModelForm):
'invalid_choice': 'Device not found.', 'invalid_choice': 'Device not found.',
} }
) )
virtual_machine = forms.ModelChoiceField(
queryset=VirtualMachine.objects.all(),
required=False,
to_field_name='name',
help_text='Name of assigned virtual machine',
error_messages={
'invalid_choice': 'Virtual machine not found.',
}
)
interface_name = forms.CharField( interface_name = forms.CharField(
help_text='Name of assigned interface', help_text='Name of assigned interface',
required=False required=False
@ -577,30 +587,47 @@ class IPAddressCSVForm(forms.ModelForm):
class Meta: class Meta:
model = IPAddress model = IPAddress
fields = ['address', 'vrf', 'tenant', 'status', 'role', 'device', 'interface_name', 'is_primary', 'description'] fields = [
'address', 'vrf', 'tenant', 'status', 'role', 'device', 'virtual_machine', 'interface_name', 'is_primary',
'description',
]
def clean(self): def clean(self):
super(IPAddressCSVForm, self).clean() super(IPAddressCSVForm, self).clean()
device = self.cleaned_data.get('device') device = self.cleaned_data.get('device')
virtual_machine = self.cleaned_data.get('virtual_machine')
interface_name = self.cleaned_data.get('interface_name') interface_name = self.cleaned_data.get('interface_name')
is_primary = self.cleaned_data.get('is_primary') is_primary = self.cleaned_data.get('is_primary')
# Validate interface # Validate interface
if device and interface_name: if interface_name and device:
try: try:
self.instance.interface = Interface.objects.get(device=device, name=interface_name) self.instance.interface = Interface.objects.get(device=device, name=interface_name)
except Interface.DoesNotExist: except Interface.DoesNotExist:
raise forms.ValidationError("Invalid interface {} for device {}".format(interface_name, device)) raise forms.ValidationError("Invalid interface {} for device {}".format(
elif device and not interface_name: interface_name, device
raise forms.ValidationError("Device set ({}) but interface missing".format(device)) ))
elif interface_name and not device: elif interface_name and virtual_machine:
raise forms.ValidationError("Interface set ({}) but device missing or invalid".format(interface_name)) try:
self.instance.interface = Interface.objects.get(virtual_machine=virtual_machine, name=interface_name)
except Interface.DoesNotExist:
raise forms.ValidationError("Invalid interface {} for virtual machine {}".format(
interface_name, virtual_machine
))
elif interface_name:
raise forms.ValidationError("Interface given ({}) but parent device/virtual machine not specified".format(
interface_name
))
elif device:
raise forms.ValidationError("Device specified ({}) but interface missing".format(device))
elif virtual_machine:
raise forms.ValidationError("Virtual machine specified ({}) but interface missing".format(virtual_machine))
# Validate is_primary # Validate is_primary
if is_primary and not device: if is_primary and not device and not virtual_machine:
raise forms.ValidationError("No device specified; cannot set as primary IP") raise forms.ValidationError("No device or virtual machine specified; cannot set as primary IP")
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
@ -610,17 +637,22 @@ class IPAddressCSVForm(forms.ModelForm):
device=self.cleaned_data['device'], device=self.cleaned_data['device'],
name=self.cleaned_data['interface_name'] name=self.cleaned_data['interface_name']
) )
elif self.cleaned_data['virtual_machine'] and self.cleaned_data['interface_name']:
self.instance.interface = Interface.objects.get(
virtual_machine=self.cleaned_data['virtual_machine'],
name=self.cleaned_data['interface_name']
)
ipaddress = super(IPAddressCSVForm, self).save(*args, **kwargs) ipaddress = super(IPAddressCSVForm, self).save(*args, **kwargs)
# Set as primary for device # Set as primary for device/VM
if self.cleaned_data['is_primary']: if self.cleaned_data['is_primary']:
device = self.cleaned_data['device'] parent = self.cleaned_data['device'] or self.cleaned_data['virtual_machine']
if self.instance.address.version == 4: if self.instance.address.version == 4:
device.primary_ip4 = ipaddress parent.primary_ip4 = ipaddress
elif self.instance.address.version == 6: elif self.instance.address.version == 6:
device.primary_ip6 = ipaddress parent.primary_ip6 = ipaddress
device.save() parent.save()
return ipaddress return ipaddress

View File

@ -420,7 +420,8 @@ class IPAddress(CreatedUpdatedModel, CustomFieldModel):
objects = IPAddressManager() objects = IPAddressManager()
csv_headers = [ csv_headers = [
'address', 'vrf', 'tenant', 'status', 'role', 'device', 'interface_name', 'is_primary', 'description', 'address', 'vrf', 'tenant', 'status', 'role', 'device', 'virtual_machine', 'interface_name', 'is_primary',
'description',
] ]
class Meta: class Meta:
@ -475,6 +476,7 @@ class IPAddress(CreatedUpdatedModel, CustomFieldModel):
self.get_status_display(), self.get_status_display(),
self.get_role_display(), self.get_role_display(),
self.device.identifier if self.device else None, self.device.identifier if self.device else None,
self.virtual_machine.name if self.device else None,
self.interface.name if self.interface else None, self.interface.name if self.interface else None,
is_primary, is_primary,
self.description, self.description,