Skip to content

Commit e5c38e0

Browse files
jeremystretchyash-pal1yash-pal1
authored
Closes #13022: Add IP assignment support when bulk importing services (#14230)
* issue 13022 resolved, ipaddress added into bulk_import form * validation of ip address for device and virtual machine * error message modified * error message modified * error message modified * Fix form validation * Extend bulk import test --------- Co-authored-by: yash-pal1 <[email protected]> Co-authored-by: yash-pal1 <[email protected]>
1 parent 6b89da2 commit e5c38e0

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

netbox/ipam/forms/bulk_import.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,10 +507,28 @@ class ServiceImportForm(NetBoxModelImportForm):
507507
choices=ServiceProtocolChoices,
508508
help_text=_('IP protocol')
509509
)
510+
ipaddresses = CSVModelMultipleChoiceField(
511+
queryset=IPAddress.objects.all(),
512+
required=False,
513+
to_field_name='address',
514+
help_text=_('IP Address'),
515+
)
510516

511517
class Meta:
512518
model = Service
513-
fields = ('device', 'virtual_machine', 'name', 'protocol', 'ports', 'description', 'comments', 'tags')
519+
fields = (
520+
'device', 'virtual_machine', 'ipaddresses', 'name', 'protocol', 'ports', 'description', 'comments', 'tags',
521+
)
522+
523+
def clean_ipaddresses(self):
524+
parent = self.cleaned_data.get('device') or self.cleaned_data.get('virtual_machine')
525+
for ip_address in self.cleaned_data['ipaddresses']:
526+
if not ip_address.assigned_object or getattr(ip_address.assigned_object, 'parent_object') != parent:
527+
raise forms.ValidationError(
528+
_("{ip} is not assigned to this device/VM.").format(ip=ip_address)
529+
)
530+
531+
return self.cleaned_data['ipaddresses']
514532

515533

516534
class L2VPNImportForm(NetBoxModelImportForm):

netbox/ipam/tests/test_views.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from django.urls import reverse
55
from netaddr import IPNetwork
66

7+
from dcim.constants import InterfaceTypeChoices
78
from dcim.models import Device, DeviceRole, DeviceType, Manufacturer, Site, Interface
89
from ipam.choices import *
910
from ipam.models import *
@@ -911,6 +912,7 @@ def setUpTestData(cls):
911912
devicetype = DeviceType.objects.create(manufacturer=manufacturer, model='Device Type 1')
912913
role = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1')
913914
device = Device.objects.create(name='Device 1', site=site, device_type=devicetype, role=role)
915+
interface = Interface.objects.create(device=device, name='Interface 1', type=InterfaceTypeChoices.TYPE_VIRTUAL)
914916

915917
services = (
916918
Service(device=device, name='Service 1', protocol=ServiceProtocolChoices.PROTOCOL_TCP, ports=[101]),
@@ -919,6 +921,12 @@ def setUpTestData(cls):
919921
)
920922
Service.objects.bulk_create(services)
921923

924+
ip_addresses = (
925+
IPAddress(assigned_object=interface, address='192.0.2.1/24'),
926+
IPAddress(assigned_object=interface, address='192.0.2.2/24'),
927+
)
928+
IPAddress.objects.bulk_create(ip_addresses)
929+
922930
tags = create_tags('Alpha', 'Bravo', 'Charlie')
923931

924932
cls.form_data = {
@@ -933,10 +941,10 @@ def setUpTestData(cls):
933941
}
934942

935943
cls.csv_data = (
936-
"device,name,protocol,ports,description",
937-
"Device 1,Service 1,tcp,1,First service",
938-
"Device 1,Service 2,tcp,2,Second service",
939-
"Device 1,Service 3,udp,3,Third service",
944+
"device,name,protocol,ports,ipaddresses,description",
945+
"Device 1,Service 1,tcp,1,192.0.2.1/24,First service",
946+
"Device 1,Service 2,tcp,2,192.0.2.2/24,Second service",
947+
"Device 1,Service 3,udp,3,,Third service",
940948
)
941949

942950
cls.csv_update_data = (

0 commit comments

Comments
 (0)