Skip to content

Commit 5a9f9af

Browse files
committed
Fixes #16871: Sanitize device ID when bulk editing components to prevent exception
1 parent 09d3646 commit 5a9f9af

File tree

1 file changed

+27
-22
lines changed

1 file changed

+27
-22
lines changed

netbox/dcim/forms/bulk_edit.py

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1188,21 +1188,26 @@ class ComponentBulkEditForm(NetBoxModelBulkEditForm):
11881188
required=False
11891189
)
11901190

1191-
def __init__(self, *args, **kwargs):
1192-
super().__init__(*args, **kwargs)
1191+
def __init__(self, *args, initial=None, **kwargs):
1192+
try:
1193+
self.device_id = int(initial.get('device'))
1194+
except (TypeError, ValueError):
1195+
self.device_id = None
1196+
1197+
super().__init__(*args, initial=initial, **kwargs)
11931198

11941199
# Limit module queryset to Modules which belong to the parent Device
1195-
if 'device' in self.initial:
1196-
device = Device.objects.filter(pk=self.initial['device']).first()
1200+
if self.device_id:
1201+
device = Device.objects.filter(pk=self.device_id).first()
11971202
self.fields['module'].queryset = Module.objects.filter(device=device)
11981203
else:
11991204
self.fields['module'].choices = ()
12001205
self.fields['module'].widget.attrs['disabled'] = True
12011206

12021207

12031208
class ConsolePortBulkEditForm(
1204-
form_from_model(ConsolePort, ['label', 'type', 'speed', 'mark_connected', 'description']),
1205-
ComponentBulkEditForm
1209+
ComponentBulkEditForm,
1210+
form_from_model(ConsolePort, ['label', 'type', 'speed', 'mark_connected', 'description'])
12061211
):
12071212
mark_connected = forms.NullBooleanField(
12081213
label=_('Mark connected'),
@@ -1218,8 +1223,8 @@ class ConsolePortBulkEditForm(
12181223

12191224

12201225
class ConsoleServerPortBulkEditForm(
1221-
form_from_model(ConsoleServerPort, ['label', 'type', 'speed', 'mark_connected', 'description']),
1222-
ComponentBulkEditForm
1226+
ComponentBulkEditForm,
1227+
form_from_model(ConsoleServerPort, ['label', 'type', 'speed', 'mark_connected', 'description'])
12231228
):
12241229
mark_connected = forms.NullBooleanField(
12251230
label=_('Mark connected'),
@@ -1235,8 +1240,8 @@ class ConsoleServerPortBulkEditForm(
12351240

12361241

12371242
class PowerPortBulkEditForm(
1238-
form_from_model(PowerPort, ['label', 'type', 'maximum_draw', 'allocated_draw', 'mark_connected', 'description']),
1239-
ComponentBulkEditForm
1243+
ComponentBulkEditForm,
1244+
form_from_model(PowerPort, ['label', 'type', 'maximum_draw', 'allocated_draw', 'mark_connected', 'description'])
12401245
):
12411246
mark_connected = forms.NullBooleanField(
12421247
label=_('Mark connected'),
@@ -1253,8 +1258,8 @@ class PowerPortBulkEditForm(
12531258

12541259

12551260
class PowerOutletBulkEditForm(
1256-
form_from_model(PowerOutlet, ['label', 'type', 'feed_leg', 'power_port', 'mark_connected', 'description']),
1257-
ComponentBulkEditForm
1261+
ComponentBulkEditForm,
1262+
form_from_model(PowerOutlet, ['label', 'type', 'feed_leg', 'power_port', 'mark_connected', 'description'])
12581263
):
12591264
mark_connected = forms.NullBooleanField(
12601265
label=_('Mark connected'),
@@ -1273,21 +1278,21 @@ def __init__(self, *args, **kwargs):
12731278
super().__init__(*args, **kwargs)
12741279

12751280
# Limit power_port queryset to PowerPorts which belong to the parent Device
1276-
if 'device' in self.initial:
1277-
device = Device.objects.filter(pk=self.initial['device']).first()
1281+
if self.device_id:
1282+
device = Device.objects.filter(pk=self.device_id).first()
12781283
self.fields['power_port'].queryset = PowerPort.objects.filter(device=device)
12791284
else:
12801285
self.fields['power_port'].choices = ()
12811286
self.fields['power_port'].widget.attrs['disabled'] = True
12821287

12831288

12841289
class InterfaceBulkEditForm(
1290+
ComponentBulkEditForm,
12851291
form_from_model(Interface, [
12861292
'label', 'type', 'parent', 'bridge', 'lag', 'speed', 'duplex', 'mac_address', 'wwn', 'mtu', 'mgmt_only',
12871293
'mark_connected', 'description', 'mode', 'rf_role', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width',
12881294
'tx_power', 'wireless_lans'
1289-
]),
1290-
ComponentBulkEditForm
1295+
])
12911296
):
12921297
enabled = forms.NullBooleanField(
12931298
label=_('Enabled'),
@@ -1416,8 +1421,8 @@ class InterfaceBulkEditForm(
14161421

14171422
def __init__(self, *args, **kwargs):
14181423
super().__init__(*args, **kwargs)
1419-
if 'device' in self.initial:
1420-
device = Device.objects.filter(pk=self.initial['device']).first()
1424+
if self.device_id:
1425+
device = Device.objects.filter(pk=self.device_id).first()
14211426

14221427
# Restrict parent/bridge/LAG interface assignment by device
14231428
self.fields['parent'].widget.add_query_param('virtual_chassis_member_id', device.pk)
@@ -1480,8 +1485,8 @@ def clean(self):
14801485

14811486

14821487
class FrontPortBulkEditForm(
1483-
form_from_model(FrontPort, ['label', 'type', 'color', 'mark_connected', 'description']),
1484-
ComponentBulkEditForm
1488+
ComponentBulkEditForm,
1489+
form_from_model(FrontPort, ['label', 'type', 'color', 'mark_connected', 'description'])
14851490
):
14861491
mark_connected = forms.NullBooleanField(
14871492
label=_('Mark connected'),
@@ -1497,8 +1502,8 @@ class FrontPortBulkEditForm(
14971502

14981503

14991504
class RearPortBulkEditForm(
1500-
form_from_model(RearPort, ['label', 'type', 'color', 'mark_connected', 'description']),
1501-
ComponentBulkEditForm
1505+
ComponentBulkEditForm,
1506+
form_from_model(RearPort, ['label', 'type', 'color', 'mark_connected', 'description'])
15021507
):
15031508
mark_connected = forms.NullBooleanField(
15041509
label=_('Mark connected'),

0 commit comments

Comments
 (0)