Przeglądaj źródła

Fixes #4166: Fix schema migrations to enforce maximum character length for naturalized fields

Jeremy Stretch 6 lat temu
rodzic
commit
909323663e

+ 8 - 0
docs/release-notes/version-2.7.md

@@ -1,3 +1,11 @@
+# v2.7.6 (FUTURE)
+
+## Bug Fixes
+
+* [#4166](https://github.com/netbox-community/netbox/issues/4166) - Fix schema migrations to enforce maximum character length for naturalized fields
+
+---
+
 # v2.7.5 (2020-02-13)
 
 **Note:** This release includes several database schema migrations that calculate and store copies of names for certain objects to improve natural ordering performance (see [#3799](https://github.com/netbox-community/netbox/issues/3799)). These migrations may take a few minutes to run if you have a very large number of objects defined in NetBox.

+ 1 - 1
netbox/dcim/migrations/0093_device_component_ordering.py

@@ -6,7 +6,7 @@ import utilities.ordering
 def _update_model_names(model):
     # Update each unique field value in bulk
     for name in model.objects.values_list('name', flat=True).order_by('name').distinct():
-        model.objects.filter(name=name).update(_name=utilities.ordering.naturalize(name))
+        model.objects.filter(name=name).update(_name=utilities.ordering.naturalize(name, max_length=100))
 
 
 def naturalize_consoleports(apps, schema_editor):

+ 1 - 1
netbox/dcim/migrations/0094_device_component_template_ordering.py

@@ -6,7 +6,7 @@ import utilities.ordering
 def _update_model_names(model):
     # Update each unique field value in bulk
     for name in model.objects.values_list('name', flat=True).order_by('name').distinct():
-        model.objects.filter(name=name).update(_name=utilities.ordering.naturalize(name))
+        model.objects.filter(name=name).update(_name=utilities.ordering.naturalize(name, max_length=100))
 
 
 def naturalize_consoleporttemplates(apps, schema_editor):

+ 1 - 1
netbox/dcim/migrations/0095_primary_model_ordering.py

@@ -6,7 +6,7 @@ import utilities.ordering
 def _update_model_names(model):
     # Update each unique field value in bulk
     for name in model.objects.values_list('name', flat=True).order_by('name').distinct():
-        model.objects.filter(name=name).update(_name=utilities.ordering.naturalize(name))
+        model.objects.filter(name=name).update(_name=utilities.ordering.naturalize(name, max_length=100))
 
 
 def naturalize_sites(apps, schema_editor):

+ 1 - 1
netbox/dcim/migrations/0096_interface_ordering.py

@@ -6,7 +6,7 @@ import utilities.ordering
 def _update_model_names(model):
     # Update each unique field value in bulk
     for name in model.objects.values_list('name', flat=True).order_by('name').distinct():
-        model.objects.filter(name=name).update(_name=utilities.ordering.naturalize_interface(name))
+        model.objects.filter(name=name).update(_name=utilities.ordering.naturalize_interface(name, max_length=100))
 
 
 def naturalize_interfacetemplates(apps, schema_editor):

+ 1 - 1
netbox/extras/management/commands/renaturalize.py

@@ -86,7 +86,7 @@ class Command(BaseCommand):
                 # Find all unique values for the field
                 queryset = model.objects.values_list(target_field, flat=True).order_by(target_field).distinct()
                 for value in queryset:
-                    naturalized_value = naturalize(value)
+                    naturalized_value = naturalize(value, max_length=field.max_length)
 
                     if options['verbosity'] >= 2:
                         self.stdout.write("  {} -> {}".format(value, naturalized_value), ending='')

+ 4 - 4
netbox/utilities/ordering.py

@@ -10,7 +10,7 @@ INTERFACE_NAME_REGEX = r'(^(?P<type>[^\d\.:]+)?)' \
                        r'(.(?P<vc>\d+)$)?'
 
 
-def naturalize(value, max_length=None, integer_places=8):
+def naturalize(value, max_length, integer_places=8):
     """
     Take an alphanumeric string and prepend all integers to `integer_places` places to ensure the strings
     are ordered naturally. For example:
@@ -39,10 +39,10 @@ def naturalize(value, max_length=None, integer_places=8):
             output.append(segment)
     ret = ''.join(output)
 
-    return ret[:max_length] if max_length else ret
+    return ret[:max_length]
 
 
-def naturalize_interface(value, max_length=None):
+def naturalize_interface(value, max_length):
     """
     Similar in nature to naturalize(), but takes into account a particular naming format adapted from the old
     InterfaceManager.
@@ -77,4 +77,4 @@ def naturalize_interface(value, max_length=None):
             output.append('000000')
 
     ret = ''.join(output)
-    return ret[:max_length] if max_length else ret
+    return ret[:max_length]

+ 8 - 2
netbox/utilities/tests/test_ordering.py

@@ -21,7 +21,10 @@ class NaturalizationTestCase(TestCase):
         )
 
         for origin, naturalized in data:
-            self.assertEqual(naturalize(origin), naturalized)
+            self.assertEqual(naturalize(origin, max_length=50), naturalized)
+
+    def test_naturalize_max_length(self):
+        self.assertEqual(naturalize('abc123def456', max_length=10), 'abc0000012')
 
     def test_naturalize_interface(self):
 
@@ -40,4 +43,7 @@ class NaturalizationTestCase(TestCase):
         )
 
         for origin, naturalized in data:
-            self.assertEqual(naturalize_interface(origin), naturalized)
+            self.assertEqual(naturalize_interface(origin, max_length=50), naturalized)
+
+    def test_naturalize_interface_max_length(self):
+        self.assertEqual(naturalize_interface('Gi1/2/3', max_length=20), '0001000299999999Gi00')