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

Fixes #1197: Fixed status assignment during bulk import of devices, prefixes, IPs, and VLANs

This commit is contained in:
Jeremy Stretch
2017-05-17 17:16:02 -04:00
parent f1cbc7da33
commit f9328d53b4
3 changed files with 42 additions and 27 deletions

View File

@ -674,7 +674,7 @@ class BaseDeviceFromCSVForm(forms.ModelForm):
queryset=Platform.objects.all(), required=False, to_field_name='name', queryset=Platform.objects.all(), required=False, to_field_name='name',
error_messages={'invalid_choice': 'Invalid platform.'} error_messages={'invalid_choice': 'Invalid platform.'}
) )
status_name = forms.ChoiceField(choices=[(s[1], s[0]) for s in STATUS_CHOICES]) status = forms.CharField()
class Meta: class Meta:
fields = [] fields = []
@ -692,8 +692,12 @@ class BaseDeviceFromCSVForm(forms.ModelForm):
except DeviceType.DoesNotExist: except DeviceType.DoesNotExist:
self.add_error('model_name', "Invalid device type ({} {})".format(manufacturer, model_name)) self.add_error('model_name', "Invalid device type ({} {})".format(manufacturer, model_name))
def clean_status_name(self): def clean_status(self):
return dict(self.fields['status_name'].choices)[self.cleaned_data['status_name']] status_choices = {s[1].lower(): s[0] for s in STATUS_CHOICES}
try:
return status_choices[self.cleaned_data['status'].lower()]
except KeyError:
raise ValidationError("Invalid status: {}".format(self.cleaned_data['status']))
class DeviceFromCSVForm(BaseDeviceFromCSVForm): class DeviceFromCSVForm(BaseDeviceFromCSVForm):
@ -707,8 +711,8 @@ class DeviceFromCSVForm(BaseDeviceFromCSVForm):
class Meta(BaseDeviceFromCSVForm.Meta): class Meta(BaseDeviceFromCSVForm.Meta):
fields = [ fields = [
'name', 'device_role', 'tenant', 'manufacturer', 'model_name', 'platform', 'serial', 'asset_tag', 'name', 'device_role', 'tenant', 'manufacturer', 'model_name', 'platform', 'serial', 'asset_tag', 'status',
'status_name', 'site', 'rack_name', 'position', 'face', 'site', 'rack_name', 'position', 'face',
] ]
def clean(self): def clean(self):
@ -751,8 +755,8 @@ class ChildDeviceFromCSVForm(BaseDeviceFromCSVForm):
class Meta(BaseDeviceFromCSVForm.Meta): class Meta(BaseDeviceFromCSVForm.Meta):
fields = [ fields = [
'name', 'device_role', 'tenant', 'manufacturer', 'model_name', 'platform', 'serial', 'asset_tag', 'name', 'device_role', 'tenant', 'manufacturer', 'model_name', 'platform', 'serial', 'asset_tag', 'status',
'status_name', 'parent', 'device_bay_name', 'parent', 'device_bay_name',
] ]
def clean(self): def clean(self):

View File

@ -1,4 +1,5 @@
from django import forms from django import forms
from django.core.exceptions import ValidationError
from django.db.models import Count from django.db.models import Count
from dcim.models import Site, Rack, Device, Interface from dcim.models import Site, Rack, Device, Interface
@ -195,14 +196,16 @@ class PrefixFromCSVForm(forms.ModelForm):
error_messages={'invalid_choice': 'Site not found.'}) error_messages={'invalid_choice': 'Site not found.'})
vlan_group_name = forms.CharField(required=False) vlan_group_name = forms.CharField(required=False)
vlan_vid = forms.IntegerField(required=False) vlan_vid = forms.IntegerField(required=False)
status_name = forms.ChoiceField(choices=[(s[1], s[0]) for s in PREFIX_STATUS_CHOICES]) status = forms.CharField()
role = forms.ModelChoiceField(queryset=Role.objects.all(), required=False, to_field_name='name', role = forms.ModelChoiceField(queryset=Role.objects.all(), required=False, to_field_name='name',
error_messages={'invalid_choice': 'Invalid role.'}) error_messages={'invalid_choice': 'Invalid role.'})
class Meta: class Meta:
model = Prefix model = Prefix
fields = ['prefix', 'vrf', 'tenant', 'site', 'vlan_group_name', 'vlan_vid', 'status_name', 'role', 'is_pool', fields = [
'description'] 'prefix', 'vrf', 'tenant', 'site', 'vlan_group_name', 'vlan_vid', 'status', 'role', 'is_pool',
'description',
]
def clean(self): def clean(self):
@ -237,12 +240,12 @@ class PrefixFromCSVForm(forms.ModelForm):
except VLAN.MultipleObjectsReturned: except VLAN.MultipleObjectsReturned:
self.add_error('vlan_vid', "Multiple VLANs found ({} - VID {})".format(site, vlan_vid)) self.add_error('vlan_vid', "Multiple VLANs found ({} - VID {})".format(site, vlan_vid))
def save(self, *args, **kwargs): def clean_status(self):
status_choices = {s[1].lower(): s[0] for s in PREFIX_STATUS_CHOICES}
# Assign Prefix status by name try:
self.instance.status = dict(self.fields['status_name'].choices)[self.cleaned_data['status_name']] return status_choices[self.cleaned_data['status'].lower()]
except KeyError:
return super(PrefixFromCSVForm, self).save(*args, **kwargs) raise ValidationError("Invalid status: {}".format(self.cleaned_data['status']))
class PrefixImportForm(BootstrapMixin, BulkImportForm): class PrefixImportForm(BootstrapMixin, BulkImportForm):
@ -491,7 +494,7 @@ class IPAddressFromCSVForm(forms.ModelForm):
error_messages={'invalid_choice': 'VRF not found.'}) error_messages={'invalid_choice': 'VRF not found.'})
tenant = forms.ModelChoiceField(Tenant.objects.all(), to_field_name='name', required=False, tenant = forms.ModelChoiceField(Tenant.objects.all(), to_field_name='name', required=False,
error_messages={'invalid_choice': 'Tenant not found.'}) error_messages={'invalid_choice': 'Tenant not found.'})
status_name = forms.ChoiceField(choices=[(s[1], s[0]) for s in IPADDRESS_STATUS_CHOICES]) status = forms.CharField()
device = forms.ModelChoiceField(queryset=Device.objects.all(), required=False, to_field_name='name', device = forms.ModelChoiceField(queryset=Device.objects.all(), required=False, to_field_name='name',
error_messages={'invalid_choice': 'Device not found.'}) error_messages={'invalid_choice': 'Device not found.'})
interface_name = forms.CharField(required=False) interface_name = forms.CharField(required=False)
@ -499,7 +502,7 @@ class IPAddressFromCSVForm(forms.ModelForm):
class Meta: class Meta:
model = IPAddress model = IPAddress
fields = ['address', 'vrf', 'tenant', 'status_name', 'device', 'interface_name', 'is_primary', 'description'] fields = ['address', 'vrf', 'tenant', 'status', 'device', 'interface_name', 'is_primary', 'description']
def clean(self): def clean(self):
@ -522,10 +525,14 @@ class IPAddressFromCSVForm(forms.ModelForm):
if is_primary and not device: if is_primary and not device:
self.add_error('is_primary', "No device specified; cannot set as primary IP") self.add_error('is_primary', "No device specified; cannot set as primary IP")
def save(self, *args, **kwargs): def clean_status(self):
status_choices = {s[1].lower(): s[0] for s in IPADDRESS_STATUS_CHOICES}
try:
return status_choices[self.cleaned_data['status'].lower()]
except KeyError:
raise ValidationError("Invalid status: {}".format(self.cleaned_data['status']))
# Assign status by name def save(self, *args, **kwargs):
self.instance.status = dict(self.fields['status_name'].choices)[self.cleaned_data['status_name']]
# Set interface # Set interface
if self.cleaned_data['device'] and self.cleaned_data['interface_name']: if self.cleaned_data['device'] and self.cleaned_data['interface_name']:
@ -650,7 +657,7 @@ class VLANFromCSVForm(forms.ModelForm):
Tenant.objects.all(), to_field_name='name', required=False, Tenant.objects.all(), to_field_name='name', required=False,
error_messages={'invalid_choice': 'Tenant not found.'} error_messages={'invalid_choice': 'Tenant not found.'}
) )
status_name = forms.ChoiceField(choices=[(s[1], s[0]) for s in VLAN_STATUS_CHOICES]) status = forms.CharField()
role = forms.ModelChoiceField( role = forms.ModelChoiceField(
queryset=Role.objects.all(), required=False, to_field_name='name', queryset=Role.objects.all(), required=False, to_field_name='name',
error_messages={'invalid_choice': 'Invalid role.'} error_messages={'invalid_choice': 'Invalid role.'}
@ -658,7 +665,7 @@ class VLANFromCSVForm(forms.ModelForm):
class Meta: class Meta:
model = VLAN model = VLAN
fields = ['site', 'group_name', 'vid', 'name', 'tenant', 'status_name', 'role', 'description'] fields = ['site', 'group_name', 'vid', 'name', 'tenant', 'status', 'role', 'description']
def clean(self): def clean(self):
@ -672,6 +679,13 @@ class VLANFromCSVForm(forms.ModelForm):
except VLANGroup.DoesNotExist: except VLANGroup.DoesNotExist:
self.add_error('group_name', "Invalid VLAN group {}.".format(group_name)) self.add_error('group_name', "Invalid VLAN group {}.".format(group_name))
def clean_status(self):
status_choices = {s[1].lower(): s[0] for s in VLAN_STATUS_CHOICES}
try:
return status_choices[self.cleaned_data['status'].lower()]
except KeyError:
raise ValidationError("Invalid status: {}".format(self.cleaned_data['status']))
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
vlan = super(VLANFromCSVForm, self).save(commit=False) vlan = super(VLANFromCSVForm, self).save(commit=False)
@ -680,9 +694,6 @@ class VLANFromCSVForm(forms.ModelForm):
if self.cleaned_data['group_name']: if self.cleaned_data['group_name']:
vlan.group = VLANGroup.objects.get(site=self.cleaned_data['site'], name=self.cleaned_data['group_name']) vlan.group = VLANGroup.objects.get(site=self.cleaned_data['site'], name=self.cleaned_data['group_name'])
# Assign VLAN status by name
vlan.status = dict(self.fields['status_name'].choices)[self.cleaned_data['status_name']]
if kwargs.get('commit'): if kwargs.get('commit'):
vlan.save() vlan.save()
return vlan return vlan

View File

@ -15,7 +15,7 @@
<tbody> <tbody>
<tr> <tr>
<td>Site</td> <td>Site</td>
<td>Name of assigned site</td> <td>Name of assigned site (optional)</td>
<td>LAS2</td> <td>LAS2</td>
</tr> </tr>
<tr> <tr>