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

Fixes #1118: Allow designating an IP as primary for a device while editing the IP

This commit is contained in:
Jeremy Stretch
2017-05-02 16:46:23 -04:00
parent 6791ff6192
commit d861d8bfb8
3 changed files with 51 additions and 8 deletions

View File

@ -344,10 +344,11 @@ class IPAddressForm(BootstrapMixin, ReturnURLForm, CustomFieldForm):
query_key='q', query_url='ipam-api:ipaddress_list', field_to_update='nat_inside', obj_label='address'
)
)
primary_for_device = forms.BooleanField(required=False, label='Make this the primary IP for the device')
class Meta:
model = IPAddress
fields = ['address', 'vrf', 'tenant', 'status', 'interface', 'nat_inside', 'description']
fields = ['address', 'vrf', 'tenant', 'status', 'description', 'interface', 'primary_for_device', 'nat_inside']
widgets = {
'interface': APISelect(api_url='/api/dcim/devices/{{interface_device}}/interfaces/'),
'nat_inside': APISelect(api_url='/api/ipam/ip-addresses/?device_id={{nat_device}}', display_field='address')
@ -388,6 +389,15 @@ class IPAddressForm(BootstrapMixin, ReturnURLForm, CustomFieldForm):
else:
self.fields['interface'].choices = []
# Initialize primary_for_device if IP address is already assigned
if self.instance.interface is not None:
device = self.instance.interface.device
if (
self.instance.address.version == 4 and device.primary_ip4 == self.instance or
self.instance.address.version == 6 and device.primary_ip6 == self.instance
):
self.initial['primary_for_device'] = True
if self.instance.nat_inside:
nat_inside = self.instance.nat_inside
# If the IP is assigned to an interface, populate site/device fields accordingly
@ -420,6 +430,43 @@ class IPAddressForm(BootstrapMixin, ReturnURLForm, CustomFieldForm):
else:
self.fields['nat_inside'].choices = []
def clean(self):
super(IPAddressForm, self).clean()
# Primary IP assignment is only available if an interface has been assigned.
if self.cleaned_data.get('primary_for_device') and not self.cleaned_data.get('interface'):
self.add_error(
'primary_for_device', "Only IP addresses assigned to an interface can be designated as primary IPs."
)
def save(self, *args, **kwargs):
ipaddress = super(IPAddressForm, self).save(*args, **kwargs)
# Assign this IPAddress as the primary for the associated Device.
if self.cleaned_data['primary_for_device']:
device = self.cleaned_data['interface'].device
if ipaddress.address.version == 4:
device.primary_ip4 = ipaddress
else:
device.primary_ip6 = ipaddress
device.save()
# Clear assignment as primary for device if set.
else:
try:
if ipaddress.address.version == 4:
device = ipaddress.primary_ip4_for
device.primary_ip4 = None
else:
device = ipaddress.primary_ip6_for
device.primary_ip6 = None
device.save()
except Device.DoesNotExist:
pass
return ipaddress
class IPAddressBulkAddForm(BootstrapMixin, CustomFieldForm):
address_pattern = ExpandableIPAddressField(label='Address Pattern')

View File

@ -28,6 +28,7 @@
{% render_field form.interface_rack %}
{% render_field form.interface_device %}
{% render_field form.interface %}
{% render_field form.primary_for_device %}
</div>
</div>
<div class="panel panel-default">

View File

@ -17,7 +17,6 @@ from django.utils.http import is_safe_url
from django.utils.safestring import mark_safe
from django.views.generic import View
from extras.forms import CustomFieldForm
from extras.models import CustomField, CustomFieldValue, ExportTemplate, UserAction
from .error_handlers import handle_protectederror
@ -195,12 +194,8 @@ class ObjectEditView(GetReturnURLMixin, View):
form = self.form_class(request.POST, instance=obj)
if form.is_valid():
obj = form.save(commit=False)
obj_created = not obj.pk
obj.save()
form.save_m2m()
if isinstance(form, CustomFieldForm):
form.save_custom_fields()
obj_created = not form.instance.pk
obj = form.save()
msg = u'Created ' if obj_created else u'Modified '
msg += self.model._meta.verbose_name