From 879166d939314bdc8745dbede3f8af67c61dd1dd Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 21 Aug 2020 15:16:33 -0400 Subject: [PATCH] Initial work on reimplementing custom fields --- .../migrations/0020_custom_field_data.py | 23 +++++++++ .../dcim/migrations/0115_custom_field_data.py | 38 ++++++++++++++ .../0050_migrate_customfieldvalues.py | 50 +++++++++++++++++++ netbox/extras/models/customfields.py | 4 ++ .../ipam/migrations/0038_custom_field_data.py | 43 ++++++++++++++++ .../migrations/0010_custom_field_data.py | 18 +++++++ .../migrations/0010_custom_field_data.py | 18 +++++++ .../migrations/0018_custom_field_data.py | 23 +++++++++ 8 files changed, 217 insertions(+) create mode 100644 netbox/circuits/migrations/0020_custom_field_data.py create mode 100644 netbox/dcim/migrations/0115_custom_field_data.py create mode 100644 netbox/extras/migrations/0050_migrate_customfieldvalues.py create mode 100644 netbox/ipam/migrations/0038_custom_field_data.py create mode 100644 netbox/secrets/migrations/0010_custom_field_data.py create mode 100644 netbox/tenancy/migrations/0010_custom_field_data.py create mode 100644 netbox/virtualization/migrations/0018_custom_field_data.py diff --git a/netbox/circuits/migrations/0020_custom_field_data.py b/netbox/circuits/migrations/0020_custom_field_data.py new file mode 100644 index 000000000..c72b937db --- /dev/null +++ b/netbox/circuits/migrations/0020_custom_field_data.py @@ -0,0 +1,23 @@ +# Generated by Django 3.1 on 2020-08-21 18:34 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('circuits', '0019_nullbooleanfield_to_booleanfield'), + ] + + operations = [ + migrations.AddField( + model_name='circuit', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict), + ), + migrations.AddField( + model_name='provider', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict), + ), + ] diff --git a/netbox/dcim/migrations/0115_custom_field_data.py b/netbox/dcim/migrations/0115_custom_field_data.py new file mode 100644 index 000000000..58c320902 --- /dev/null +++ b/netbox/dcim/migrations/0115_custom_field_data.py @@ -0,0 +1,38 @@ +# Generated by Django 3.1 on 2020-08-21 18:34 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0114_update_jsonfield'), + ] + + operations = [ + migrations.AddField( + model_name='device', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict), + ), + migrations.AddField( + model_name='devicetype', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict), + ), + migrations.AddField( + model_name='powerfeed', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict), + ), + migrations.AddField( + model_name='rack', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict), + ), + migrations.AddField( + model_name='site', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict), + ), + ] diff --git a/netbox/extras/migrations/0050_migrate_customfieldvalues.py b/netbox/extras/migrations/0050_migrate_customfieldvalues.py new file mode 100644 index 000000000..9b2402267 --- /dev/null +++ b/netbox/extras/migrations/0050_migrate_customfieldvalues.py @@ -0,0 +1,50 @@ +from django.db import migrations + +from extras.choices import CustomFieldTypeChoices + + +def deserialize_value(field_type, value): + """ + Convert serialized values to JSON equivalents. + """ + if field_type in (CustomFieldTypeChoices.TYPE_INTEGER, CustomFieldTypeChoices.TYPE_SELECT): + return int(value) + if field_type == CustomFieldTypeChoices.TYPE_BOOLEAN: + return bool(int(value)) + return value + + +def migrate_customfieldvalues(apps, schema_editor): + CustomFieldValue = apps.get_model('extras', 'CustomFieldValue') + + for cfv in CustomFieldValue.objects.prefetch_related('field').exclude(serialized_value=''): + model = apps.get_model(cfv.obj_type.app_label, cfv.obj_type.model) + + # Read and update custom field value for each instance + # TODO: This can be done more efficiently once .update() is supported for JSON fields + cf_data = model.objects.filter(pk=cfv.obj_id).values('custom_field_data').first() + try: + cf_data['custom_field_data'][cfv.field.name] = deserialize_value(cfv.field.type, cfv.serialized_value) + except ValueError as e: + print(f'{cfv.field.name} ({cfv.field.type}): {cfv.serialized_value} ({cfv.pk})') + raise e + model.objects.filter(pk=cfv.obj_id).update(**cf_data) + + +class Migration(migrations.Migration): + + dependencies = [ + ('circuits', '0020_custom_field_data'), + ('dcim', '0115_custom_field_data'), + ('extras', '0049_remove_graph'), + ('ipam', '0038_custom_field_data'), + ('secrets', '0010_custom_field_data'), + ('tenancy', '0010_custom_field_data'), + ('virtualization', '0018_custom_field_data'), + ] + + operations = [ + migrations.RunPython( + code=migrate_customfieldvalues + ), + ] diff --git a/netbox/extras/models/customfields.py b/netbox/extras/models/customfields.py index fd09971b6..1c86812e0 100644 --- a/netbox/extras/models/customfields.py +++ b/netbox/extras/models/customfields.py @@ -17,6 +17,10 @@ from extras.utils import FeatureQuery # class CustomFieldModel(models.Model): + custom_field_data = models.JSONField( + blank=True, + default=dict + ) class Meta: abstract = True diff --git a/netbox/ipam/migrations/0038_custom_field_data.py b/netbox/ipam/migrations/0038_custom_field_data.py new file mode 100644 index 000000000..c9d66975c --- /dev/null +++ b/netbox/ipam/migrations/0038_custom_field_data.py @@ -0,0 +1,43 @@ +# Generated by Django 3.1 on 2020-08-21 18:34 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0037_ipaddress_assignment'), + ] + + operations = [ + migrations.AddField( + model_name='aggregate', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict), + ), + migrations.AddField( + model_name='ipaddress', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict), + ), + migrations.AddField( + model_name='prefix', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict), + ), + migrations.AddField( + model_name='service', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict), + ), + migrations.AddField( + model_name='vlan', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict), + ), + migrations.AddField( + model_name='vrf', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict), + ), + ] diff --git a/netbox/secrets/migrations/0010_custom_field_data.py b/netbox/secrets/migrations/0010_custom_field_data.py new file mode 100644 index 000000000..33b5f06e1 --- /dev/null +++ b/netbox/secrets/migrations/0010_custom_field_data.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1 on 2020-08-21 18:34 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('secrets', '0009_secretrole_drop_users_groups'), + ] + + operations = [ + migrations.AddField( + model_name='secret', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict), + ), + ] diff --git a/netbox/tenancy/migrations/0010_custom_field_data.py b/netbox/tenancy/migrations/0010_custom_field_data.py new file mode 100644 index 000000000..4d05a8272 --- /dev/null +++ b/netbox/tenancy/migrations/0010_custom_field_data.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1 on 2020-08-21 18:34 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('tenancy', '0009_standardize_description'), + ] + + operations = [ + migrations.AddField( + model_name='tenant', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict), + ), + ] diff --git a/netbox/virtualization/migrations/0018_custom_field_data.py b/netbox/virtualization/migrations/0018_custom_field_data.py new file mode 100644 index 000000000..5c129e2ab --- /dev/null +++ b/netbox/virtualization/migrations/0018_custom_field_data.py @@ -0,0 +1,23 @@ +# Generated by Django 3.1 on 2020-08-21 18:34 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('virtualization', '0017_update_jsonfield'), + ] + + operations = [ + migrations.AddField( + model_name='cluster', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict), + ), + migrations.AddField( + model_name='virtualmachine', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict), + ), + ]