mirror of
https://github.com/netbox-community/netbox.git
synced 2025-12-26 15:17:45 -06:00
Merge branch 'develop' into v2-develop
Conflicts: netbox/dcim/forms.py netbox/dcim/views.py netbox/ipam/forms.py netbox/templates/_base.html netbox/utilities/views.py
This commit is contained in:
@@ -1422,9 +1422,16 @@ class InterfaceBulkEditForm(BootstrapMixin, BulkEditForm):
|
||||
super(InterfaceBulkEditForm, self).__init__(*args, **kwargs)
|
||||
|
||||
# Limit LAG choices to interfaces which belong to the parent device.
|
||||
device = None
|
||||
if self.initial.get('device'):
|
||||
self.fields['lag'].queryset = Interface.objects.filter(
|
||||
device=self.initial['device'], form_factor=IFACE_FF_LAG
|
||||
try:
|
||||
device = Device.objects.get(pk=self.initial.get('device'))
|
||||
except Device.DoesNotExist:
|
||||
pass
|
||||
if device is not None:
|
||||
interface_ordering = device.device_type.interface_ordering
|
||||
self.fields['lag'].queryset = Interface.objects.order_naturally(method=interface_ordering).filter(
|
||||
device=device, form_factor=IFACE_FF_LAG
|
||||
)
|
||||
else:
|
||||
self.fields['lag'].choices = []
|
||||
@@ -1684,36 +1691,6 @@ class InterfaceConnectionFilterForm(BootstrapMixin, forms.Form):
|
||||
device = forms.CharField(required=False, label='Device name')
|
||||
|
||||
|
||||
#
|
||||
# IP addresses
|
||||
#
|
||||
|
||||
class IPAddressForm(BootstrapMixin, CustomFieldForm):
|
||||
set_as_primary = forms.BooleanField(label='Set as primary IP for device', required=False)
|
||||
|
||||
class Meta:
|
||||
model = IPAddress
|
||||
fields = ['address', 'vrf', 'tenant', 'status', 'interface', 'description']
|
||||
|
||||
def __init__(self, device, *args, **kwargs):
|
||||
|
||||
super(IPAddressForm, self).__init__(*args, **kwargs)
|
||||
|
||||
self.fields['vrf'].empty_label = 'Global'
|
||||
|
||||
interfaces = device.interfaces.all()
|
||||
self.fields['interface'].queryset = interfaces
|
||||
self.fields['interface'].required = True
|
||||
|
||||
# If this device has only one interface, select it by default.
|
||||
if len(interfaces) == 1:
|
||||
self.fields['interface'].initial = interfaces[0]
|
||||
|
||||
# If this device does not have any IP addresses assigned, default to setting the first IP as its primary.
|
||||
if not IPAddress.objects.filter(interface__device=device).count():
|
||||
self.fields['set_as_primary'].initial = True
|
||||
|
||||
|
||||
#
|
||||
# Inventory items
|
||||
#
|
||||
|
||||
@@ -121,7 +121,6 @@ urlpatterns = [
|
||||
url(r'^devices/(?P<pk>\d+)/delete/$', views.DeviceDeleteView.as_view(), name='device_delete'),
|
||||
url(r'^devices/(?P<pk>\d+)/inventory/$', views.device_inventory, name='device_inventory'),
|
||||
url(r'^devices/(?P<pk>\d+)/lldp-neighbors/$', views.device_lldp_neighbors, name='device_lldp_neighbors'),
|
||||
url(r'^devices/(?P<pk>\d+)/ip-addresses/assign/$', views.ipaddress_assign, name='ipaddress_assign'),
|
||||
url(r'^devices/(?P<pk>\d+)/add-secret/$', secret_add, name='device_addsecret'),
|
||||
url(r'^devices/(?P<device>\d+)/services/assign/$', ServiceEditView.as_view(), name='service_assign'),
|
||||
url(r'^devices/(?P<object_id>\d+)/images/add/$', ImageAttachmentEditView.as_view(), name='device_add_image', kwargs={'model': Device}),
|
||||
|
||||
@@ -13,7 +13,7 @@ from django.urls import reverse
|
||||
from django.utils.http import urlencode
|
||||
from django.views.generic import View
|
||||
|
||||
from ipam.models import Prefix, IPAddress, Service, VLAN
|
||||
from ipam.models import Prefix, Service, VLAN
|
||||
from circuits.models import Circuit
|
||||
from extras.models import Graph, TopologyMap, GRAPH_TYPE_INTERFACE, GRAPH_TYPE_SITE
|
||||
from utilities.forms import ConfirmationForm
|
||||
@@ -124,13 +124,13 @@ class ComponentCreateView(View):
|
||||
|
||||
class ComponentEditView(ObjectEditView):
|
||||
|
||||
def get_return_url(self, obj):
|
||||
def get_return_url(self, request, obj):
|
||||
return obj.device.get_absolute_url()
|
||||
|
||||
|
||||
class ComponentDeleteView(ObjectDeleteView):
|
||||
|
||||
def get_return_url(self, obj):
|
||||
def get_return_url(self, request, obj):
|
||||
return obj.device.get_absolute_url()
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@ class RegionEditView(PermissionRequiredMixin, ObjectEditView):
|
||||
model = Region
|
||||
form_class = forms.RegionForm
|
||||
|
||||
def get_return_url(self, obj):
|
||||
def get_return_url(self, request, obj):
|
||||
return reverse('dcim:region_list')
|
||||
|
||||
|
||||
@@ -242,7 +242,7 @@ class RackGroupEditView(PermissionRequiredMixin, ObjectEditView):
|
||||
model = RackGroup
|
||||
form_class = forms.RackGroupForm
|
||||
|
||||
def get_return_url(self, obj):
|
||||
def get_return_url(self, request, obj):
|
||||
return reverse('dcim:rackgroup_list')
|
||||
|
||||
|
||||
@@ -268,7 +268,7 @@ class RackRoleEditView(PermissionRequiredMixin, ObjectEditView):
|
||||
model = RackRole
|
||||
form_class = forms.RackRoleForm
|
||||
|
||||
def get_return_url(self, obj):
|
||||
def get_return_url(self, request, obj):
|
||||
return reverse('dcim:rackrole_list')
|
||||
|
||||
|
||||
@@ -379,7 +379,7 @@ class RackReservationEditView(PermissionRequiredMixin, ObjectEditView):
|
||||
obj.user = request.user
|
||||
return obj
|
||||
|
||||
def get_return_url(self, obj):
|
||||
def get_return_url(self, request, obj):
|
||||
return obj.rack.get_absolute_url()
|
||||
|
||||
|
||||
@@ -387,7 +387,7 @@ class RackReservationDeleteView(PermissionRequiredMixin, ObjectDeleteView):
|
||||
permission_required = 'dcim.delete_rackreservation'
|
||||
model = RackReservation
|
||||
|
||||
def get_return_url(self, obj):
|
||||
def get_return_url(self, request, obj):
|
||||
return obj.rack.get_absolute_url()
|
||||
|
||||
|
||||
@@ -412,7 +412,7 @@ class ManufacturerEditView(PermissionRequiredMixin, ObjectEditView):
|
||||
model = Manufacturer
|
||||
form_class = forms.ManufacturerForm
|
||||
|
||||
def get_return_url(self, obj):
|
||||
def get_return_url(self, request, obj):
|
||||
return reverse('dcim:manufacturer_list')
|
||||
|
||||
|
||||
@@ -632,7 +632,7 @@ class DeviceRoleEditView(PermissionRequiredMixin, ObjectEditView):
|
||||
model = DeviceRole
|
||||
form_class = forms.DeviceRoleForm
|
||||
|
||||
def get_return_url(self, obj):
|
||||
def get_return_url(self, request, obj):
|
||||
return reverse('dcim:devicerole_list')
|
||||
|
||||
|
||||
@@ -657,7 +657,7 @@ class PlatformEditView(PermissionRequiredMixin, ObjectEditView):
|
||||
model = Platform
|
||||
form_class = forms.PlatformForm
|
||||
|
||||
def get_return_url(self, obj):
|
||||
def get_return_url(self, request, obj):
|
||||
return reverse('dcim:platform_list')
|
||||
|
||||
|
||||
@@ -700,19 +700,15 @@ def device(request, pk):
|
||||
interfaces = Interface.objects.order_naturally(device.device_type.interface_ordering)\
|
||||
.filter(device=device, mgmt_only=False)\
|
||||
.select_related('connected_as_a__interface_b__device', 'connected_as_b__interface_a__device',
|
||||
'circuit_termination__circuit')
|
||||
'circuit_termination__circuit').prefetch_related('ip_addresses')
|
||||
mgmt_interfaces = Interface.objects.order_naturally(device.device_type.interface_ordering)\
|
||||
.filter(device=device, mgmt_only=True)\
|
||||
.select_related('connected_as_a__interface_b__device', 'connected_as_b__interface_a__device',
|
||||
'circuit_termination__circuit')
|
||||
'circuit_termination__circuit').prefetch_related('ip_addresses')
|
||||
device_bays = natsorted(
|
||||
DeviceBay.objects.filter(device=device).select_related('installed_device__device_type__manufacturer'),
|
||||
key=attrgetter('name')
|
||||
)
|
||||
|
||||
# Gather relevant device objects
|
||||
ip_addresses = IPAddress.objects.filter(interface__device=device).select_related('interface', 'vrf')\
|
||||
.order_by('address')
|
||||
services = Service.objects.filter(device=device)
|
||||
secrets = device.secrets.all()
|
||||
|
||||
@@ -743,7 +739,6 @@ def device(request, pk):
|
||||
'interfaces': interfaces,
|
||||
'mgmt_interfaces': mgmt_interfaces,
|
||||
'device_bays': device_bays,
|
||||
'ip_addresses': ip_addresses,
|
||||
'services': services,
|
||||
'secrets': secrets,
|
||||
'related_devices': related_devices,
|
||||
@@ -755,7 +750,6 @@ class DeviceEditView(PermissionRequiredMixin, ObjectEditView):
|
||||
permission_required = 'dcim.change_device'
|
||||
model = Device
|
||||
form_class = forms.DeviceForm
|
||||
fields_initial = ['site', 'rack', 'position', 'face', 'device_bay']
|
||||
template_name = 'dcim/device_edit.html'
|
||||
default_return_url = 'dcim:device_list'
|
||||
|
||||
@@ -1567,47 +1561,6 @@ class InterfaceConnectionsListView(ObjectListView):
|
||||
template_name = 'dcim/interface_connections_list.html'
|
||||
|
||||
|
||||
#
|
||||
# IP addresses
|
||||
#
|
||||
|
||||
@permission_required(['dcim.change_device', 'ipam.add_ipaddress'])
|
||||
def ipaddress_assign(request, pk):
|
||||
|
||||
device = get_object_or_404(Device, pk=pk)
|
||||
|
||||
if request.method == 'POST':
|
||||
form = forms.IPAddressForm(device, request.POST)
|
||||
if form.is_valid():
|
||||
|
||||
ipaddress = form.save(commit=False)
|
||||
ipaddress.interface = form.cleaned_data['interface']
|
||||
ipaddress.save()
|
||||
form.save_custom_fields()
|
||||
messages.success(request, u"Added new IP address {} to interface {}.".format(ipaddress, ipaddress.interface))
|
||||
|
||||
if form.cleaned_data['set_as_primary']:
|
||||
if ipaddress.family == 4:
|
||||
device.primary_ip4 = ipaddress
|
||||
elif ipaddress.family == 6:
|
||||
device.primary_ip6 = ipaddress
|
||||
device.save()
|
||||
|
||||
if '_addanother' in request.POST:
|
||||
return redirect('dcim:ipaddress_assign', pk=device.pk)
|
||||
else:
|
||||
return redirect('dcim:device', pk=device.pk)
|
||||
|
||||
else:
|
||||
form = forms.IPAddressForm(device)
|
||||
|
||||
return render(request, 'dcim/ipaddress_assign.html', {
|
||||
'device': device,
|
||||
'form': form,
|
||||
'return_url': reverse('dcim:device', kwargs={'pk': device.pk}),
|
||||
})
|
||||
|
||||
|
||||
#
|
||||
# Inventory items
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user