|
|
@@ -1,5 +1,7 @@
|
|
|
from django.db import migrations
|
|
|
|
|
|
+from ipam.utils import rebuild_prefixes
|
|
|
+
|
|
|
|
|
|
def push_to_stack(stack, prefix):
|
|
|
# Increment child count on parent nodes
|
|
|
@@ -22,54 +24,12 @@ def populate_prefix_hierarchy(apps, schema_editor):
|
|
|
total_count = Prefix.objects.count()
|
|
|
print(f'\nUpdating {total_count} prefixes...')
|
|
|
|
|
|
- # Iterate through all VRFs and the global table
|
|
|
- vrfs = [None] + list(VRF.objects.values_list('pk', flat=True))
|
|
|
- for vrf in vrfs:
|
|
|
-
|
|
|
- stack = []
|
|
|
- update_queue = []
|
|
|
-
|
|
|
- # Iterate through all Prefixes in the VRF, growing and shrinking the stack as we go
|
|
|
- prefixes = Prefix.objects.filter(vrf=vrf).values('pk', 'prefix')
|
|
|
- for i, p in enumerate(prefixes):
|
|
|
-
|
|
|
- # Grow the stack if this is a child of the most recent prefix
|
|
|
- if not stack or p['prefix'] in stack[-1]['prefix']:
|
|
|
- push_to_stack(stack, p)
|
|
|
-
|
|
|
- # If this is a sibling or parent of the most recent prefix, pop nodes from the
|
|
|
- # stack until we reach a parent prefix (or the root)
|
|
|
- else:
|
|
|
- while stack and p['prefix'] not in stack[-1]['prefix'] and p['prefix'] != stack[-1]['prefix']:
|
|
|
- node = stack.pop()
|
|
|
- update_queue.append(
|
|
|
- Prefix(
|
|
|
- pk=node['pk'],
|
|
|
- _depth=len(stack),
|
|
|
- _children=node['children']
|
|
|
- )
|
|
|
- )
|
|
|
- push_to_stack(stack, p)
|
|
|
-
|
|
|
- # Flush the update queue once it reaches 100 Prefixes
|
|
|
- if len(update_queue) >= 100:
|
|
|
- Prefix.objects.bulk_update(update_queue, ['_depth', '_children'])
|
|
|
- update_queue = []
|
|
|
- print(f' [{i}/{total_count}]')
|
|
|
-
|
|
|
- # Clear out any prefixes remaining in the stack
|
|
|
- while stack:
|
|
|
- node = stack.pop()
|
|
|
- update_queue.append(
|
|
|
- Prefix(
|
|
|
- pk=node['pk'],
|
|
|
- _depth=len(stack),
|
|
|
- _children=node['children']
|
|
|
- )
|
|
|
- )
|
|
|
+ # Rebuild the global table
|
|
|
+ rebuild_prefixes(None)
|
|
|
|
|
|
- # Final flush of any remaining Prefixes
|
|
|
- Prefix.objects.bulk_update(update_queue, ['_depth', '_children'])
|
|
|
+ # Iterate through all VRFs, rebuilding each
|
|
|
+ for vrf in VRF.objects.all():
|
|
|
+ rebuild_prefixes(vrf)
|
|
|
|
|
|
|
|
|
class Migration(migrations.Migration):
|