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

Optimize schema migration for VM interface replication

This commit is contained in:
Jeremy Stretch
2020-08-10 13:53:28 -04:00
parent 365b6f5e17
commit d7e2acd0ad

View File

@ -16,11 +16,14 @@ def replicate_interfaces(apps, schema_editor):
vminterface_ct = ContentType.objects.get_for_model(VMInterface) vminterface_ct = ContentType.objects.get_for_model(VMInterface)
# Replicate dcim.Interface instances assigned to VirtualMachines # Replicate dcim.Interface instances assigned to VirtualMachines
original_interfaces = Interface.objects.filter(virtual_machine__isnull=False) original_interfaces = Interface.objects.prefetch_related('tagged_vlans').filter(
virtual_machine__isnull=False
)
interfaces_count = len(original_interfaces)
if show_output: if show_output:
print(f"\n Replicating {len(original_interfaces)} VM interfaces...", end='', flush=True) print(f"\n Replicating {interfaces_count} VM interfaces...", flush=True)
for i, interface in enumerate(original_interfaces, start=1): new_interfaces = [
vminterface = VMInterface( VMInterface(
virtual_machine=interface.virtual_machine, virtual_machine=interface.virtual_machine,
name=interface.name, name=interface.name,
enabled=interface.enabled, enabled=interface.enabled,
@ -29,29 +32,45 @@ def replicate_interfaces(apps, schema_editor):
mode=interface.mode, mode=interface.mode,
description=interface.description, description=interface.description,
untagged_vlan=interface.untagged_vlan, untagged_vlan=interface.untagged_vlan,
) ) for interface in original_interfaces
vminterface.save() ]
VMInterface.objects.bulk_create(new_interfaces, batch_size=1000)
# Pre-fetch the PKs of interfaces with tags/IP addresses
interfaces_with_tags = TaggedItem.objects.filter(
content_type=interface_ct
).values_list('object_id', flat=True)
interfaces_with_ips = IPAddress.objects.filter(
assigned_object_id__isnull=False
).values_list('assigned_object_id', flat=True)
if show_output:
print(f" Replicating assigned objects...", flush=True)
for i, interface in enumerate(original_interfaces):
vminterface = new_interfaces[i]
# Copy tagged VLANs # Copy tagged VLANs
if interface.tagged_vlans.exists():
vminterface.tagged_vlans.set(interface.tagged_vlans.all()) vminterface.tagged_vlans.set(interface.tagged_vlans.all())
# Reassign tags to the new instance # Reassign tags to the new instance
TaggedItem.objects.filter( if interface.pk in interfaces_with_tags:
content_type=interface_ct, object_id=interface.pk TaggedItem.objects.filter(content_type=interface_ct, object_id=interface.pk).update(
).update( content_type=vminterface_ct,
content_type=vminterface_ct, object_id=vminterface.pk object_id=vminterface.pk
) )
# Update any assigned IPAddresses # Update any assigned IPAddresses
IPAddress.objects.filter(assigned_object_id=interface.pk).update( if interface.pk in interfaces_with_ips:
IPAddress.objects.filter(assigned_object_type=interface_ct, assigned_object_id=interface.pk).update(
assigned_object_type=vminterface_ct, assigned_object_type=vminterface_ct,
assigned_object_id=vminterface.pk assigned_object_id=vminterface.pk
) )
# Progress counter # Progress counter
if show_output and not i % 250: if show_output and not i % 1000:
percentage = int(i / len(original_interfaces) * 100) percentage = int(i / interfaces_count * 100)
print(f" {i}/{len(original_interfaces)} ({percentage}%)", flush=True) print(f" {i}/{interfaces_count} ({percentage}%)", flush=True)
# Verify that all interfaces have been replicated # Verify that all interfaces have been replicated
replicated_count = VMInterface.objects.count() replicated_count = VMInterface.objects.count()