diff --git a/netbox/account/migrations/0001_initial.py b/netbox/account/migrations/0001_initial.py index 37ff73d5b..72c079565 100644 --- a/netbox/account/migrations/0001_initial.py +++ b/netbox/account/migrations/0001_initial.py @@ -1,3 +1,5 @@ +# Generated by Django 4.1.10 on 2023-07-30 17:49 + from django.db import migrations diff --git a/netbox/circuits/migrations/0001_initial.py b/netbox/circuits/migrations/0001_squashed.py similarity index 52% rename from netbox/circuits/migrations/0001_initial.py rename to netbox/circuits/migrations/0001_squashed.py index c5b95b930..96fa3c086 100644 --- a/netbox/circuits/migrations/0001_initial.py +++ b/netbox/circuits/migrations/0001_squashed.py @@ -1,6 +1,7 @@ +import ipam.fields +from utilities.json import CustomFieldJSONEncoder from django.db import migrations, models import django.db.models.deletion -import utilities.json class Migration(migrations.Migration): @@ -10,36 +11,36 @@ class Migration(migrations.Migration): dependencies = [ ] + replaces = [ + ('circuits', '0001_initial'), + ] + operations = [ migrations.CreateModel( name='Circuit', fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('created', models.DateField(auto_now_add=True, null=True)), ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), ('cid', models.CharField(max_length=100)), ('status', models.CharField(default='active', max_length=50)), ('install_date', models.DateField(blank=True, null=True)), - ('termination_date', models.DateField(blank=True, null=True)), ('commit_rate', models.PositiveIntegerField(blank=True, null=True)), + ('description', models.CharField(blank=True, max_length=200)), + ('comments', models.TextField(blank=True)), ], options={ - 'verbose_name': 'circuit', - 'verbose_name_plural': 'circuits', - 'ordering': ['provider', 'provider_account', 'cid'], + 'ordering': ['provider', 'cid'], }, ), migrations.CreateModel( name='CircuitTermination', fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('created', models.DateField(auto_now_add=True, null=True)), ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('cable_end', models.CharField(blank=True, max_length=1)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)), ('mark_connected', models.BooleanField(default=False)), ('term_side', models.CharField(max_length=1)), ('port_speed', models.PositiveIntegerField(blank=True, null=True)), @@ -49,80 +50,57 @@ class Migration(migrations.Migration): ('description', models.CharField(blank=True, max_length=200)), ], options={ - 'verbose_name': 'circuit termination', - 'verbose_name_plural': 'circuit terminations', 'ordering': ['circuit', 'term_side'], }, ), migrations.CreateModel( name='CircuitType', fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('created', models.DateField(auto_now_add=True, null=True)), ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), ('name', models.CharField(max_length=100, unique=True)), ('slug', models.SlugField(max_length=100, unique=True)), ('description', models.CharField(blank=True, max_length=200)), ], options={ - 'verbose_name': 'circuit type', - 'verbose_name_plural': 'circuit types', 'ordering': ('name',), }, ), migrations.CreateModel( name='Provider', fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('created', models.DateField(auto_now_add=True, null=True)), ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), ('name', models.CharField(max_length=100, unique=True)), ('slug', models.SlugField(max_length=100, unique=True)), - ], - options={ - 'verbose_name': 'provider', - 'verbose_name_plural': 'providers', - 'ordering': ['name'], - }, - ), - migrations.CreateModel( - name='ProviderAccount', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), + ('asn', ipam.fields.ASNField(blank=True, null=True)), + ('account', models.CharField(blank=True, max_length=30)), + ('portal_url', models.URLField(blank=True)), + ('noc_contact', models.TextField(blank=True)), + ('admin_contact', models.TextField(blank=True)), ('comments', models.TextField(blank=True)), - ('account', models.CharField(max_length=100)), - ('name', models.CharField(blank=True, max_length=100)), ], options={ - 'verbose_name': 'provider account', - 'verbose_name_plural': 'provider accounts', - 'ordering': ('provider', 'account'), + 'ordering': ['name'], }, ), migrations.CreateModel( name='ProviderNetwork', fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('created', models.DateField(auto_now_add=True, null=True)), ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100)), ('description', models.CharField(blank=True, max_length=200)), ('comments', models.TextField(blank=True)), - ('name', models.CharField(max_length=100)), - ('service_id', models.CharField(blank=True, max_length=100)), ('provider', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='networks', to='circuits.provider')), ], options={ - 'verbose_name': 'provider network', - 'verbose_name_plural': 'provider networks', 'ordering': ('provider', 'name'), }, ), diff --git a/netbox/circuits/migrations/0004_squashed.py b/netbox/circuits/migrations/0002_squashed_0029.py similarity index 53% rename from netbox/circuits/migrations/0004_squashed.py rename to netbox/circuits/migrations/0002_squashed_0029.py index 6dcd80e8c..11fcbd6e6 100644 --- a/netbox/circuits/migrations/0004_squashed.py +++ b/netbox/circuits/migrations/0002_squashed_0029.py @@ -1,13 +1,15 @@ from django.db import migrations, models import django.db.models.deletion +import taggit.managers class Migration(migrations.Migration): - initial = True - dependencies = [ - ('circuits', '0003_squashed'), + ('dcim', '0001_initial'), + ('contenttypes', '0002_remove_content_type_name'), + ('circuits', '0001_initial'), + ('extras', '0001_initial'), ('tenancy', '0001_initial'), ] @@ -40,22 +42,54 @@ class Migration(migrations.Migration): ('circuits', '0027_providernetwork'), ('circuits', '0028_cache_circuit_terminations'), ('circuits', '0029_circuit_tracing'), - ('circuits', '0003_extend_tag_support'), # Misnumbered - ('circuits', '0004_rename_cable_peer'), # Misnumbered - ('circuits', '0032_provider_service_id'), - ('circuits', '0033_standardize_id_fields'), - ('circuits', '0034_created_datetimefield'), - ('circuits', '0035_provider_asns'), - ('circuits', '0036_circuit_termination_date_tags_custom_fields'), - ('circuits', '0037_new_cabling_models'), - ('circuits', '0038_cabling_cleanup'), - ('circuits', '0039_unique_constraints'), - ('circuits', '0040_provider_remove_deprecated_fields'), - ('circuits', '0041_standardize_description_comments'), - ('circuits', '0042_provideraccount'), ] operations = [ + migrations.AddField( + model_name='providernetwork', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='provider', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='circuittermination', + name='_cable_peer_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'), + ), + migrations.AddField( + model_name='circuittermination', + name='cable', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'), + ), + migrations.AddField( + model_name='circuittermination', + name='circuit', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='terminations', to='circuits.circuit'), + ), + migrations.AddField( + model_name='circuittermination', + name='provider_network', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='circuit_terminations', to='circuits.providernetwork'), + ), + migrations.AddField( + model_name='circuittermination', + name='site', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='circuit_terminations', to='dcim.site'), + ), + migrations.AddField( + model_name='circuit', + name='provider', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='circuits.provider'), + ), + migrations.AddField( + model_name='circuit', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), migrations.AddField( model_name='circuit', name='tenant', @@ -78,26 +112,18 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='providernetwork', - constraint=models.UniqueConstraint(fields=('provider', 'name'), name='circuits_providernetwork_unique_provider_name'), + constraint=models.UniqueConstraint(fields=('provider', 'name'), name='circuits_providernetwork_provider_name'), ), - migrations.AddConstraint( - model_name='provideraccount', - constraint=models.UniqueConstraint(fields=('provider', 'account'), name='circuits_provideraccount_unique_provider_account'), + migrations.AlterUniqueTogether( + name='providernetwork', + unique_together={('provider', 'name')}, ), - migrations.AddConstraint( - model_name='provideraccount', - constraint=models.UniqueConstraint(condition=models.Q(('name', ''), _negated=True), fields=('provider', 'name'), name='circuits_provideraccount_unique_provider_name'), + migrations.AlterUniqueTogether( + name='circuittermination', + unique_together={('circuit', 'term_side')}, ), - migrations.AddConstraint( - model_name='circuittermination', - constraint=models.UniqueConstraint(fields=('circuit', 'term_side'), name='circuits_circuittermination_unique_circuit_term_side'), - ), - migrations.AddConstraint( - model_name='circuit', - constraint=models.UniqueConstraint(fields=('provider', 'cid'), name='circuits_circuit_unique_provider_cid'), - ), - migrations.AddConstraint( - model_name='circuit', - constraint=models.UniqueConstraint(fields=('provider_account', 'cid'), name='circuits_circuit_unique_provideraccount_cid'), + migrations.AlterUniqueTogether( + name='circuit', + unique_together={('provider', 'cid')}, ), ] diff --git a/netbox/circuits/migrations/0003_extend_tag_support.py b/netbox/circuits/migrations/0003_extend_tag_support.py new file mode 100644 index 000000000..e5e6ee262 --- /dev/null +++ b/netbox/circuits/migrations/0003_extend_tag_support.py @@ -0,0 +1,20 @@ +# Generated by Django 3.2.8 on 2021-10-21 14:50 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0062_clear_secrets_changelog'), + ('circuits', '0002_squashed_0029'), + ] + + operations = [ + migrations.AddField( + model_name='circuittype', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + ] diff --git a/netbox/circuits/migrations/0003_squashed.py b/netbox/circuits/migrations/0003_squashed.py deleted file mode 100644 index 84a96755e..000000000 --- a/netbox/circuits/migrations/0003_squashed.py +++ /dev/null @@ -1,73 +0,0 @@ -from django.db import migrations, models -import django.db.models.deletion -import taggit.managers - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ('extras', '0001_initial'), - ('ipam', '0001_initial'), - ('dcim', '0001_initial'), - ('circuits', '0002_squashed'), - ] - - operations = [ - migrations.AddField( - model_name='provider', - name='asns', - field=models.ManyToManyField(blank=True, related_name='providers', to='ipam.asn'), - ), - migrations.AddField( - model_name='provider', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='circuittype', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='circuittermination', - name='cable', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'), - ), - migrations.AddField( - model_name='circuittermination', - name='circuit', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='terminations', to='circuits.circuit'), - ), - migrations.AddField( - model_name='circuittermination', - name='provider_network', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='circuit_terminations', to='circuits.providernetwork'), - ), - migrations.AddField( - model_name='circuittermination', - name='site', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='circuit_terminations', to='dcim.site'), - ), - migrations.AddField( - model_name='circuittermination', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='circuit', - name='provider', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='circuits.provider'), - ), - migrations.AddField( - model_name='circuit', - name='provider_account', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='circuits.provideraccount'), - ), - migrations.AddField( - model_name='circuit', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - ] diff --git a/netbox/circuits/migrations/0004_rename_cable_peer.py b/netbox/circuits/migrations/0004_rename_cable_peer.py new file mode 100644 index 000000000..81d507eb4 --- /dev/null +++ b/netbox/circuits/migrations/0004_rename_cable_peer.py @@ -0,0 +1,21 @@ +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('circuits', '0003_extend_tag_support'), + ] + + operations = [ + migrations.RenameField( + model_name='circuittermination', + old_name='_cable_peer_id', + new_name='_link_peer_id', + ), + migrations.RenameField( + model_name='circuittermination', + old_name='_cable_peer_type', + new_name='_link_peer_type', + ), + ] diff --git a/netbox/circuits/migrations/0032_provider_service_id.py b/netbox/circuits/migrations/0032_provider_service_id.py new file mode 100644 index 000000000..58936d1bd --- /dev/null +++ b/netbox/circuits/migrations/0032_provider_service_id.py @@ -0,0 +1,17 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('circuits', '0004_rename_cable_peer'), + ('dcim', '0145_site_remove_deprecated_fields'), + ] + + operations = [ + migrations.AddField( + model_name='providernetwork', + name='service_id', + field=models.CharField(blank=True, max_length=100), + ), + ] diff --git a/netbox/circuits/migrations/0033_standardize_id_fields.py b/netbox/circuits/migrations/0033_standardize_id_fields.py new file mode 100644 index 000000000..475fc2527 --- /dev/null +++ b/netbox/circuits/migrations/0033_standardize_id_fields.py @@ -0,0 +1,44 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('circuits', '0032_provider_service_id'), + ] + + operations = [ + # Model IDs + migrations.AlterField( + model_name='circuit', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='circuittermination', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='circuittype', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='provider', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='providernetwork', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + + # GFK IDs + migrations.AlterField( + model_name='circuittermination', + name='_link_peer_id', + field=models.PositiveBigIntegerField(blank=True, null=True), + ), + ] diff --git a/netbox/circuits/migrations/0034_created_datetimefield.py b/netbox/circuits/migrations/0034_created_datetimefield.py new file mode 100644 index 000000000..4af78c1a2 --- /dev/null +++ b/netbox/circuits/migrations/0034_created_datetimefield.py @@ -0,0 +1,38 @@ +# Generated by Django 4.0.2 on 2022-02-08 18:54 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('circuits', '0033_standardize_id_fields'), + ] + + operations = [ + migrations.AlterField( + model_name='circuit', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='circuittermination', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='circuittype', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='provider', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='providernetwork', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + ] diff --git a/netbox/circuits/migrations/0035_provider_asns.py b/netbox/circuits/migrations/0035_provider_asns.py new file mode 100644 index 000000000..afb0da4d6 --- /dev/null +++ b/netbox/circuits/migrations/0035_provider_asns.py @@ -0,0 +1,19 @@ +# Generated by Django 4.0.3 on 2022-03-30 20:27 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0057_created_datetimefield'), + ('circuits', '0034_created_datetimefield'), + ] + + operations = [ + migrations.AddField( + model_name='provider', + name='asns', + field=models.ManyToManyField(blank=True, related_name='providers', to='ipam.asn'), + ), + ] diff --git a/netbox/circuits/migrations/0036_circuit_termination_date_tags_custom_fields.py b/netbox/circuits/migrations/0036_circuit_termination_date_tags_custom_fields.py new file mode 100644 index 000000000..96b2a9d97 --- /dev/null +++ b/netbox/circuits/migrations/0036_circuit_termination_date_tags_custom_fields.py @@ -0,0 +1,28 @@ +from utilities.json import CustomFieldJSONEncoder +from django.db import migrations, models +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ('circuits', '0035_provider_asns'), + ] + + operations = [ + migrations.AddField( + model_name='circuit', + name='termination_date', + field=models.DateField(blank=True, null=True), + ), + migrations.AddField( + model_name='circuittermination', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder), + ), + migrations.AddField( + model_name='circuittermination', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + ] diff --git a/netbox/circuits/migrations/0037_new_cabling_models.py b/netbox/circuits/migrations/0037_new_cabling_models.py new file mode 100644 index 000000000..ee08147f3 --- /dev/null +++ b/netbox/circuits/migrations/0037_new_cabling_models.py @@ -0,0 +1,16 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('circuits', '0036_circuit_termination_date_tags_custom_fields'), + ] + + operations = [ + migrations.AddField( + model_name='circuittermination', + name='cable_end', + field=models.CharField(blank=True, max_length=1), + ), + ] diff --git a/netbox/circuits/migrations/0038_cabling_cleanup.py b/netbox/circuits/migrations/0038_cabling_cleanup.py new file mode 100644 index 000000000..0672057e3 --- /dev/null +++ b/netbox/circuits/migrations/0038_cabling_cleanup.py @@ -0,0 +1,20 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('circuits', '0037_new_cabling_models'), + ('dcim', '0160_populate_cable_ends'), + ] + + operations = [ + migrations.RemoveField( + model_name='circuittermination', + name='_link_peer_id', + ), + migrations.RemoveField( + model_name='circuittermination', + name='_link_peer_type', + ), + ] diff --git a/netbox/circuits/migrations/0039_unique_constraints.py b/netbox/circuits/migrations/0039_unique_constraints.py new file mode 100644 index 000000000..1d5b62499 --- /dev/null +++ b/netbox/circuits/migrations/0039_unique_constraints.py @@ -0,0 +1,39 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('circuits', '0038_cabling_cleanup'), + ] + + operations = [ + migrations.RemoveConstraint( + model_name='providernetwork', + name='circuits_providernetwork_provider_name', + ), + migrations.AlterUniqueTogether( + name='circuit', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='circuittermination', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='providernetwork', + unique_together=set(), + ), + migrations.AddConstraint( + model_name='circuit', + constraint=models.UniqueConstraint(fields=('provider', 'cid'), name='circuits_circuit_unique_provider_cid'), + ), + migrations.AddConstraint( + model_name='circuittermination', + constraint=models.UniqueConstraint(fields=('circuit', 'term_side'), name='circuits_circuittermination_unique_circuit_term_side'), + ), + migrations.AddConstraint( + model_name='providernetwork', + constraint=models.UniqueConstraint(fields=('provider', 'name'), name='circuits_providernetwork_unique_provider_name'), + ), + ] diff --git a/netbox/circuits/migrations/0040_provider_remove_deprecated_fields.py b/netbox/circuits/migrations/0040_provider_remove_deprecated_fields.py new file mode 100644 index 000000000..98c82204d --- /dev/null +++ b/netbox/circuits/migrations/0040_provider_remove_deprecated_fields.py @@ -0,0 +1,59 @@ +import os + +from django.db import migrations +from django.db.utils import DataError + + +def check_legacy_data(apps, schema_editor): + """ + Abort the migration if any legacy provider fields still contain data. + """ + Provider = apps.get_model('circuits', 'Provider') + + provider_count = Provider.objects.exclude(asn__isnull=True).count() + if provider_count and 'NETBOX_DELETE_LEGACY_DATA' not in os.environ: + raise DataError( + f"Unable to proceed with deleting asn field from Provider model: Found {provider_count} " + f"providers with legacy ASN data. Please ensure all legacy provider ASN data has been " + f"migrated to ASN objects before proceeding. Or, set the NETBOX_DELETE_LEGACY_DATA " + f"environment variable to bypass this safeguard and delete all legacy provider ASN data." + ) + + provider_count = Provider.objects.exclude(admin_contact='', noc_contact='', portal_url='').count() + if provider_count and 'NETBOX_DELETE_LEGACY_DATA' not in os.environ: + raise DataError( + f"Unable to proceed with deleting contact fields from Provider model: Found {provider_count} " + f"providers with legacy contact data. Please ensure all legacy provider contact data has been " + f"migrated to contact objects before proceeding. Or, set the NETBOX_DELETE_LEGACY_DATA " + f"environment variable to bypass this safeguard and delete all legacy provider contact data." + ) + + +class Migration(migrations.Migration): + + dependencies = [ + ('circuits', '0039_unique_constraints'), + ] + + operations = [ + migrations.RunPython( + code=check_legacy_data, + reverse_code=migrations.RunPython.noop + ), + migrations.RemoveField( + model_name='provider', + name='admin_contact', + ), + migrations.RemoveField( + model_name='provider', + name='asn', + ), + migrations.RemoveField( + model_name='provider', + name='noc_contact', + ), + migrations.RemoveField( + model_name='provider', + name='portal_url', + ), + ] diff --git a/netbox/circuits/migrations/0041_standardize_description_comments.py b/netbox/circuits/migrations/0041_standardize_description_comments.py new file mode 100644 index 000000000..49cdefcba --- /dev/null +++ b/netbox/circuits/migrations/0041_standardize_description_comments.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.2 on 2022-11-03 18:24 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('circuits', '0040_provider_remove_deprecated_fields'), + ] + + operations = [ + migrations.AddField( + model_name='provider', + name='description', + field=models.CharField(blank=True, max_length=200), + ), + ] diff --git a/netbox/circuits/migrations/0042_provideraccount.py b/netbox/circuits/migrations/0042_provideraccount.py new file mode 100644 index 000000000..3e583844e --- /dev/null +++ b/netbox/circuits/migrations/0042_provideraccount.py @@ -0,0 +1,91 @@ +from django.db import migrations, models +import django.db.models.deletion +import taggit.managers +import utilities.json + + +def create_provideraccounts_from_providers(apps, schema_editor): + """ + Migrate Account in Provider model to separate account model + """ + Provider = apps.get_model('circuits', 'Provider') + ProviderAccount = apps.get_model('circuits', 'ProviderAccount') + + provider_accounts = [] + for provider in Provider.objects.all(): + if provider.account: + provider_accounts.append(ProviderAccount( + provider=provider, + account=provider.account + )) + ProviderAccount.objects.bulk_create(provider_accounts, batch_size=100) + + +def restore_providers_from_provideraccounts(apps, schema_editor): + """ + Restore Provider account values from auto-generated ProviderAccounts + """ + ProviderAccount = apps.get_model('circuits', 'ProviderAccount') + provider_accounts = ProviderAccount.objects.order_by('pk') + for provideraccount in provider_accounts: + if provider_accounts.filter(provider=provideraccount.provider)[0] == provideraccount: + provideraccount.provider.account = provideraccount.account + provideraccount.provider.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0084_staging'), + ('circuits', '0041_standardize_description_comments'), + ] + + operations = [ + migrations.CreateModel( + name='ProviderAccount', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), + ('description', models.CharField(blank=True, max_length=200)), + ('comments', models.TextField(blank=True)), + ('account', models.CharField(max_length=100)), + ('name', models.CharField(blank=True, max_length=100)), + ('provider', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='accounts', to='circuits.provider')), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ], + options={ + 'ordering': ('provider', 'account'), + }, + ), + migrations.AddConstraint( + model_name='provideraccount', + constraint=models.UniqueConstraint(condition=models.Q(('name', ''), _negated=True), fields=('provider', 'name'), name='circuits_provideraccount_unique_provider_name'), + ), + migrations.AddConstraint( + model_name='provideraccount', + constraint=models.UniqueConstraint(fields=('provider', 'account'), name='circuits_provideraccount_unique_provider_account'), + ), + migrations.RunPython( + create_provideraccounts_from_providers, restore_providers_from_provideraccounts + ), + migrations.RemoveField( + model_name='provider', + name='account', + ), + migrations.AddField( + model_name='circuit', + name='provider_account', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='circuits.provideraccount', null=True, blank=True), + preserve_default=False, + ), + migrations.AlterModelOptions( + name='circuit', + options={'ordering': ['provider', 'provider_account', 'cid']}, + ), + migrations.AddConstraint( + model_name='circuit', + constraint=models.UniqueConstraint(fields=('provider_account', 'cid'), name='circuits_circuit_unique_provideraccount_cid'), + ), + ] diff --git a/netbox/circuits/migrations/0043_circuittype_color.py b/netbox/circuits/migrations/0043_circuittype_color.py index 6eb14b86f..6c4dffeb6 100644 --- a/netbox/circuits/migrations/0043_circuittype_color.py +++ b/netbox/circuits/migrations/0043_circuittype_color.py @@ -1,3 +1,5 @@ +# Generated by Django 4.2.5 on 2023-10-20 21:25 + from django.db import migrations import utilities.fields diff --git a/netbox/core/migrations/0001_initial.py b/netbox/core/migrations/0001_initial.py index 374121fdf..775a5dcb1 100644 --- a/netbox/core/migrations/0001_initial.py +++ b/netbox/core/migrations/0001_initial.py @@ -1,8 +1,9 @@ -from django.conf import settings +# Generated by Django 4.1.5 on 2023-02-02 02:37 + import django.core.validators from django.db import migrations, models import django.db.models.deletion -import extras.utils +import taggit.managers import utilities.json @@ -11,39 +12,10 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('contenttypes', '0002_remove_content_type_name'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('extras', '0084_staging'), ] operations = [ - migrations.CreateModel( - name='AutoSyncRecord', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('object_id', models.PositiveBigIntegerField()), - ], - options={ - 'verbose_name': 'auto sync record', - 'verbose_name_plural': 'auto sync records', - }, - ), - migrations.CreateModel( - name='DataFile', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True)), - ('last_updated', models.DateTimeField(editable=False)), - ('path', models.CharField(editable=False, max_length=1000)), - ('size', models.PositiveIntegerField(editable=False)), - ('hash', models.CharField(editable=False, max_length=64, validators=[django.core.validators.RegexValidator(message='Length must be 64 hexadecimal characters.', regex='^[0-9a-f]{64}$')])), - ('data', models.BinaryField()), - ], - options={ - 'verbose_name': 'data file', - 'verbose_name_plural': 'data files', - 'ordering': ('source', 'path'), - }, - ), migrations.CreateModel( name='DataSource', fields=[ @@ -61,54 +33,51 @@ class Migration(migrations.Migration): ('ignore_rules', models.TextField(blank=True)), ('parameters', models.JSONField(blank=True, null=True)), ('last_synced', models.DateTimeField(blank=True, editable=False, null=True)), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), ], options={ - 'verbose_name': 'data source', - 'verbose_name_plural': 'data sources', 'ordering': ('name',), }, ), migrations.CreateModel( - name='ManagedFile', + name='DataFile', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('data_path', models.CharField(blank=True, editable=False, max_length=1000)), - ('auto_sync_enabled', models.BooleanField(default=False)), - ('data_synced', models.DateTimeField(blank=True, editable=False, null=True)), ('created', models.DateTimeField(auto_now_add=True)), - ('last_updated', models.DateTimeField(blank=True, editable=False, null=True)), - ('file_root', models.CharField(max_length=1000)), - ('file_path', models.FilePathField(editable=False)), - ('data_file', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='core.datafile')), - ('data_source', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='core.datasource')), + ('last_updated', models.DateTimeField(editable=False)), + ('path', models.CharField(editable=False, max_length=1000)), + ('size', models.PositiveIntegerField(editable=False)), + ('hash', models.CharField(editable=False, max_length=64, validators=[django.core.validators.RegexValidator(message='Length must be 64 hexadecimal characters.', regex='^[0-9a-f]{64}$')])), + ('data', models.BinaryField()), + ('source', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='datafiles', to='core.datasource')), ], options={ - 'verbose_name': 'managed file', - 'verbose_name_plural': 'managed files', - 'ordering': ('file_root', 'file_path'), + 'ordering': ('source', 'path'), }, ), + migrations.AddConstraint( + model_name='datafile', + constraint=models.UniqueConstraint(fields=('source', 'path'), name='core_datafile_unique_source_path'), + ), + migrations.AddIndex( + model_name='datafile', + index=models.Index(fields=['source', 'path'], name='core_datafile_source_path'), + ), migrations.CreateModel( - name='Job', + name='AutoSyncRecord', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('object_id', models.PositiveBigIntegerField(blank=True, null=True)), - ('name', models.CharField(max_length=200)), - ('created', models.DateTimeField(auto_now_add=True)), - ('scheduled', models.DateTimeField(blank=True, null=True)), - ('interval', models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)])), - ('started', models.DateTimeField(blank=True, null=True)), - ('completed', models.DateTimeField(blank=True, null=True)), - ('status', models.CharField(default='pending', max_length=30)), - ('data', models.JSONField(blank=True, null=True)), - ('job_id', models.UUIDField(unique=True)), - ('object_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='jobs', to='contenttypes.contenttype')), - ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)), + ('object_id', models.PositiveBigIntegerField()), + ('datafile', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='core.datafile')), + ('object_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='contenttypes.contenttype')), ], - options={ - 'verbose_name': 'job', - 'verbose_name_plural': 'jobs', - 'ordering': ['-created'], - }, + ), + migrations.AddIndex( + model_name='autosyncrecord', + index=models.Index(fields=['object_type', 'object_id'], name='core_autosy_object__c17bac_idx'), + ), + migrations.AddConstraint( + model_name='autosyncrecord', + constraint=models.UniqueConstraint(fields=('object_type', 'object_id'), name='core_autosyncrecord_object'), ), ] diff --git a/netbox/core/migrations/0002_managedfile.py b/netbox/core/migrations/0002_managedfile.py new file mode 100644 index 000000000..169063be8 --- /dev/null +++ b/netbox/core/migrations/0002_managedfile.py @@ -0,0 +1,40 @@ +# Generated by Django 4.1.7 on 2023-03-23 17:35 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='ManagedFile', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('data_path', models.CharField(blank=True, editable=False, max_length=1000)), + ('data_synced', models.DateTimeField(blank=True, editable=False, null=True)), + ('created', models.DateTimeField(auto_now_add=True)), + ('last_updated', models.DateTimeField(blank=True, editable=False, null=True)), + ('file_root', models.CharField(max_length=1000)), + ('file_path', models.FilePathField(editable=False)), + ('data_file', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='core.datafile')), + ('data_source', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='core.datasource')), + ('auto_sync_enabled', models.BooleanField(default=False)), + ], + options={ + 'ordering': ('file_root', 'file_path'), + }, + ), + migrations.AddIndex( + model_name='managedfile', + index=models.Index(fields=['file_root', 'file_path'], name='core_managedfile_root_path'), + ), + migrations.AddConstraint( + model_name='managedfile', + constraint=models.UniqueConstraint(fields=('file_root', 'file_path'), name='core_managedfile_unique_root_path'), + ), + ] diff --git a/netbox/core/migrations/0002_squashed.py b/netbox/core/migrations/0002_squashed.py deleted file mode 100644 index 6e2f03ce3..000000000 --- a/netbox/core/migrations/0002_squashed.py +++ /dev/null @@ -1,68 +0,0 @@ -from django.db import migrations, models -import django.db.models.deletion -import taggit.managers - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ('extras', '0001_initial'), - ('contenttypes', '0002_remove_content_type_name'), - ('core', '0001_initial'), - ] - - replaces = [ - ('core', '0002_managedfile'), - ('core', '0003_job'), - ('core', '0004_replicate_jobresults'), - ('core', '0005_job_created_auto_now'), - ] - - operations = [ - migrations.AddField( - model_name='datasource', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='datafile', - name='source', - field=models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='datafiles', to='core.datasource'), - ), - migrations.AddField( - model_name='autosyncrecord', - name='datafile', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='core.datafile'), - ), - migrations.AddField( - model_name='autosyncrecord', - name='object_type', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='contenttypes.contenttype'), - ), - migrations.AddIndex( - model_name='managedfile', - index=models.Index(fields=['file_root', 'file_path'], name='core_managedfile_root_path'), - ), - migrations.AddConstraint( - model_name='managedfile', - constraint=models.UniqueConstraint(fields=('file_root', 'file_path'), name='core_managedfile_unique_root_path'), - ), - migrations.AddIndex( - model_name='datafile', - index=models.Index(fields=['source', 'path'], name='core_datafile_source_path'), - ), - migrations.AddConstraint( - model_name='datafile', - constraint=models.UniqueConstraint(fields=('source', 'path'), name='core_datafile_unique_source_path'), - ), - migrations.AddIndex( - model_name='autosyncrecord', - index=models.Index(fields=['object_type', 'object_id'], name='core_autosy_object__c17bac_idx'), - ), - migrations.AddConstraint( - model_name='autosyncrecord', - constraint=models.UniqueConstraint(fields=('object_type', 'object_id'), name='core_autosyncrecord_object'), - ), - ] diff --git a/netbox/core/migrations/0003_job.py b/netbox/core/migrations/0003_job.py new file mode 100644 index 000000000..f2fe41afb --- /dev/null +++ b/netbox/core/migrations/0003_job.py @@ -0,0 +1,39 @@ +# Generated by Django 4.1.7 on 2023-03-27 15:02 + +from django.conf import settings +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('core', '0002_managedfile'), + ] + + operations = [ + migrations.CreateModel( + name='Job', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('object_id', models.PositiveBigIntegerField(blank=True, null=True)), + ('name', models.CharField(max_length=200)), + ('created', models.DateTimeField()), + ('scheduled', models.DateTimeField(blank=True, null=True)), + ('interval', models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)])), + ('started', models.DateTimeField(blank=True, null=True)), + ('completed', models.DateTimeField(blank=True, null=True)), + ('status', models.CharField(default='pending', max_length=30)), + ('data', models.JSONField(blank=True, null=True)), + ('job_id', models.UUIDField(unique=True)), + ('object_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='jobs', to='contenttypes.contenttype')), + ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'ordering': ['-created'], + }, + ), + ] diff --git a/netbox/core/migrations/0004_replicate_jobresults.py b/netbox/core/migrations/0004_replicate_jobresults.py new file mode 100644 index 000000000..881506b9b --- /dev/null +++ b/netbox/core/migrations/0004_replicate_jobresults.py @@ -0,0 +1,46 @@ +from django.db import migrations + + +def replicate_jobresults(apps, schema_editor): + """ + Replicate existing JobResults to the new Jobs table before deleting the old JobResults table. + """ + Job = apps.get_model('core', 'Job') + JobResult = apps.get_model('extras', 'JobResult') + + jobs = [] + for job_result in JobResult.objects.order_by('pk').iterator(chunk_size=100): + jobs.append( + Job( + object_type=job_result.obj_type, + name=job_result.name, + created=job_result.created, + scheduled=job_result.scheduled, + interval=job_result.interval, + started=job_result.started, + completed=job_result.completed, + user=job_result.user, + status=job_result.status, + data=job_result.data, + job_id=job_result.job_id, + ) + ) + if len(jobs) == 100: + Job.objects.bulk_create(jobs) + jobs = [] + if jobs: + Job.objects.bulk_create(jobs) + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0003_job'), + ] + + operations = [ + migrations.RunPython( + code=replicate_jobresults, + reverse_code=migrations.RunPython.noop + ), + ] diff --git a/netbox/core/migrations/0005_job_created_auto_now.py b/netbox/core/migrations/0005_job_created_auto_now.py new file mode 100644 index 000000000..12fd526ef --- /dev/null +++ b/netbox/core/migrations/0005_job_created_auto_now.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.7 on 2023-03-27 17:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0004_replicate_jobresults'), + ] + + operations = [ + migrations.AlterField( + model_name='job', + name='created', + field=models.DateTimeField(auto_now_add=True), + ), + ] diff --git a/netbox/core/migrations/0006_datasource_type_remove_choices.py b/netbox/core/migrations/0006_datasource_type_remove_choices.py index 4c8adcd72..0ad8d8854 100644 --- a/netbox/core/migrations/0006_datasource_type_remove_choices.py +++ b/netbox/core/migrations/0006_datasource_type_remove_choices.py @@ -1,3 +1,5 @@ +# Generated by Django 4.2.6 on 2023-10-20 17:47 + from django.db import migrations, models diff --git a/netbox/dcim/migrations/0001_initial.py b/netbox/dcim/migrations/0001_initial.py deleted file mode 100644 index 7f0437b17..000000000 --- a/netbox/dcim/migrations/0001_initial.py +++ /dev/null @@ -1,979 +0,0 @@ -# Generated by Django 4.2.9 on 2024-01-18 18:27 - -import dcim.fields -import django.contrib.postgres.fields -import django.core.validators -from django.db import migrations, models -import django.db.models.deletion -import timezone_field.fields -import utilities.fields -import utilities.json -import utilities.ordering -import utilities.query_functions -import utilities.tracking -import utilities.validators - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ] - - operations = [ - migrations.CreateModel( - name='Cable', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('type', models.CharField(blank=True, max_length=50)), - ('status', models.CharField(default='connected', max_length=50)), - ('label', models.CharField(blank=True, max_length=100)), - ('color', utilities.fields.ColorField(blank=True, max_length=6)), - ('length', models.DecimalField(blank=True, decimal_places=2, max_digits=8, null=True)), - ('length_unit', models.CharField(blank=True, max_length=50)), - ('_abs_length', models.DecimalField(blank=True, decimal_places=4, max_digits=10, null=True)), - ], - options={ - 'verbose_name': 'cable', - 'verbose_name_plural': 'cables', - 'ordering': ('pk',), - }, - ), - migrations.CreateModel( - name='CablePath', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('path', models.JSONField(default=list)), - ('is_active', models.BooleanField(default=False)), - ('is_complete', models.BooleanField(default=False)), - ('is_split', models.BooleanField(default=False)), - ('_nodes', dcim.fields.PathField(base_field=models.CharField(max_length=40), size=None)), - ], - options={ - 'verbose_name': 'cable path', - 'verbose_name_plural': 'cable paths', - }, - ), - migrations.CreateModel( - name='CableTermination', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('cable_end', models.CharField(max_length=1)), - ('termination_id', models.PositiveBigIntegerField()), - ], - options={ - 'verbose_name': 'cable termination', - 'verbose_name_plural': 'cable terminations', - 'ordering': ('cable', 'cable_end', 'pk'), - }, - ), - migrations.CreateModel( - name='ConsolePort', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=64)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), - ('label', models.CharField(blank=True, max_length=64)), - ('description', models.CharField(blank=True, max_length=200)), - ('cable_end', models.CharField(blank=True, max_length=1)), - ('mark_connected', models.BooleanField(default=False)), - ('type', models.CharField(blank=True, max_length=50)), - ('speed', models.PositiveIntegerField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'console port', - 'verbose_name_plural': 'console ports', - 'ordering': ('device', '_name'), - 'abstract': False, - }, - bases=(models.Model, utilities.tracking.TrackingModelMixin), - ), - migrations.CreateModel( - name='ConsolePortTemplate', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('name', models.CharField(max_length=64)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), - ('label', models.CharField(blank=True, max_length=64)), - ('description', models.CharField(blank=True, max_length=200)), - ('type', models.CharField(blank=True, max_length=50)), - ], - options={ - 'verbose_name': 'console port template', - 'verbose_name_plural': 'console port templates', - 'ordering': ('device_type', 'module_type', '_name'), - 'abstract': False, - }, - bases=(models.Model, utilities.tracking.TrackingModelMixin), - ), - migrations.CreateModel( - name='ConsoleServerPort', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=64)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), - ('label', models.CharField(blank=True, max_length=64)), - ('description', models.CharField(blank=True, max_length=200)), - ('cable_end', models.CharField(blank=True, max_length=1)), - ('mark_connected', models.BooleanField(default=False)), - ('type', models.CharField(blank=True, max_length=50)), - ('speed', models.PositiveIntegerField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'console server port', - 'verbose_name_plural': 'console server ports', - 'ordering': ('device', '_name'), - 'abstract': False, - }, - bases=(models.Model, utilities.tracking.TrackingModelMixin), - ), - migrations.CreateModel( - name='ConsoleServerPortTemplate', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('name', models.CharField(max_length=64)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), - ('label', models.CharField(blank=True, max_length=64)), - ('description', models.CharField(blank=True, max_length=200)), - ('type', models.CharField(blank=True, max_length=50)), - ], - options={ - 'verbose_name': 'console server port template', - 'verbose_name_plural': 'console server port templates', - 'ordering': ('device_type', 'module_type', '_name'), - 'abstract': False, - }, - bases=(models.Model, utilities.tracking.TrackingModelMixin), - ), - migrations.CreateModel( - name='Device', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('local_context_data', models.JSONField(blank=True, null=True)), - ('name', models.CharField(blank=True, max_length=64, null=True)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize, null=True)), - ('serial', models.CharField(blank=True, max_length=50)), - ('asset_tag', models.CharField(blank=True, max_length=50, null=True, unique=True)), - ('position', models.DecimalField(blank=True, decimal_places=1, max_digits=4, null=True, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(100.5)])), - ('face', models.CharField(blank=True, max_length=50)), - ('status', models.CharField(default='active', max_length=50)), - ('airflow', models.CharField(blank=True, max_length=50)), - ('vc_position', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(255)])), - ('vc_priority', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(255)])), - ('latitude', models.DecimalField(blank=True, decimal_places=6, max_digits=8, null=True)), - ('longitude', models.DecimalField(blank=True, decimal_places=6, max_digits=9, null=True)), - ('console_port_count', utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.ConsolePort')), - ('console_server_port_count', utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.ConsoleServerPort')), - ('power_port_count', utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.PowerPort')), - ('power_outlet_count', utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.PowerOutlet')), - ('interface_count', utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.Interface')), - ('front_port_count', utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.FrontPort')), - ('rear_port_count', utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.RearPort')), - ('device_bay_count', utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.DeviceBay')), - ('module_bay_count', utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.ModuleBay')), - ('inventory_item_count', utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.InventoryItem')), - ], - options={ - 'verbose_name': 'device', - 'verbose_name_plural': 'devices', - 'ordering': ('_name', 'pk'), - }, - bases=(utilities.tracking.TrackingModelMixin, models.Model), - ), - migrations.CreateModel( - name='DeviceBay', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=64)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), - ('label', models.CharField(blank=True, max_length=64)), - ('description', models.CharField(blank=True, max_length=200)), - ], - options={ - 'verbose_name': 'device bay', - 'verbose_name_plural': 'device bays', - 'ordering': ('device', '_name'), - 'abstract': False, - }, - bases=(models.Model, utilities.tracking.TrackingModelMixin), - ), - migrations.CreateModel( - name='DeviceBayTemplate', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('name', models.CharField(max_length=64)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), - ('label', models.CharField(blank=True, max_length=64)), - ('description', models.CharField(blank=True, max_length=200)), - ], - options={ - 'verbose_name': 'device bay template', - 'verbose_name_plural': 'device bay templates', - 'ordering': ('device_type', '_name'), - 'abstract': False, - }, - bases=(models.Model, utilities.tracking.TrackingModelMixin), - ), - migrations.CreateModel( - name='DeviceRole', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=100, unique=True)), - ('slug', models.SlugField(max_length=100, unique=True)), - ('description', models.CharField(blank=True, max_length=200)), - ('color', utilities.fields.ColorField(default='9e9e9e', max_length=6)), - ('vm_role', models.BooleanField(default=True)), - ], - options={ - 'verbose_name': 'device role', - 'verbose_name_plural': 'device roles', - 'ordering': ('name',), - }, - ), - migrations.CreateModel( - name='DeviceType', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('weight', models.DecimalField(blank=True, decimal_places=2, max_digits=8, null=True)), - ('weight_unit', models.CharField(blank=True, max_length=50)), - ('_abs_weight', models.PositiveBigIntegerField(blank=True, null=True)), - ('model', models.CharField(max_length=100)), - ('slug', models.SlugField(max_length=100)), - ('part_number', models.CharField(blank=True, max_length=50)), - ('u_height', models.DecimalField(decimal_places=1, default=1.0, max_digits=4)), - ('is_full_depth', models.BooleanField(default=True)), - ('subdevice_role', models.CharField(blank=True, max_length=50)), - ('airflow', models.CharField(blank=True, max_length=50)), - ('front_image', models.ImageField(blank=True, upload_to='devicetype-images')), - ('rear_image', models.ImageField(blank=True, upload_to='devicetype-images')), - ('console_port_template_count', utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.ConsolePortTemplate')), - ('console_server_port_template_count', utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.ConsoleServerPortTemplate')), - ('power_port_template_count', utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.PowerPortTemplate')), - ('power_outlet_template_count', utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.PowerOutletTemplate')), - ('interface_template_count', utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.InterfaceTemplate')), - ('front_port_template_count', utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.FrontPortTemplate')), - ('rear_port_template_count', utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.RearPortTemplate')), - ('device_bay_template_count', utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.DeviceBayTemplate')), - ('module_bay_template_count', utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.ModuleBayTemplate')), - ('inventory_item_template_count', utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.InventoryItemTemplate')), - ], - options={ - 'verbose_name': 'device type', - 'verbose_name_plural': 'device types', - 'ordering': ['manufacturer', 'model'], - }, - ), - migrations.CreateModel( - name='FrontPort', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=64)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), - ('label', models.CharField(blank=True, max_length=64)), - ('description', models.CharField(blank=True, max_length=200)), - ('cable_end', models.CharField(blank=True, max_length=1)), - ('mark_connected', models.BooleanField(default=False)), - ('type', models.CharField(max_length=50)), - ('color', utilities.fields.ColorField(blank=True, max_length=6)), - ('rear_port_position', models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(1024)])), - ], - options={ - 'verbose_name': 'front port', - 'verbose_name_plural': 'front ports', - 'ordering': ('device', '_name'), - 'abstract': False, - }, - bases=(models.Model, utilities.tracking.TrackingModelMixin), - ), - migrations.CreateModel( - name='FrontPortTemplate', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('name', models.CharField(max_length=64)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), - ('label', models.CharField(blank=True, max_length=64)), - ('description', models.CharField(blank=True, max_length=200)), - ('type', models.CharField(max_length=50)), - ('color', utilities.fields.ColorField(blank=True, max_length=6)), - ('rear_port_position', models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(1024)])), - ], - options={ - 'verbose_name': 'front port template', - 'verbose_name_plural': 'front port templates', - 'ordering': ('device_type', 'module_type', '_name'), - 'abstract': False, - }, - bases=(models.Model, utilities.tracking.TrackingModelMixin), - ), - migrations.CreateModel( - name='Interface', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=64)), - ('label', models.CharField(blank=True, max_length=64)), - ('description', models.CharField(blank=True, max_length=200)), - ('cable_end', models.CharField(blank=True, max_length=1)), - ('mark_connected', models.BooleanField(default=False)), - ('enabled', models.BooleanField(default=True)), - ('mac_address', dcim.fields.MACAddressField(blank=True, null=True)), - ('mtu', models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(65536)])), - ('mode', models.CharField(blank=True, max_length=50)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize_interface)), - ('type', models.CharField(max_length=50)), - ('mgmt_only', models.BooleanField(default=False)), - ('speed', models.PositiveIntegerField(blank=True, null=True)), - ('duplex', models.CharField(blank=True, max_length=50, null=True)), - ('wwn', dcim.fields.WWNField(blank=True, null=True)), - ('rf_role', models.CharField(blank=True, max_length=30)), - ('rf_channel', models.CharField(blank=True, max_length=50)), - ('rf_channel_frequency', models.DecimalField(blank=True, decimal_places=2, max_digits=7, null=True)), - ('rf_channel_width', models.DecimalField(blank=True, decimal_places=3, max_digits=7, null=True)), - ('tx_power', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(127)])), - ('poe_mode', models.CharField(blank=True, max_length=50)), - ('poe_type', models.CharField(blank=True, max_length=50)), - ], - options={ - 'verbose_name': 'interface', - 'verbose_name_plural': 'interfaces', - 'ordering': ('device', utilities.query_functions.CollateAsChar('_name')), - 'abstract': False, - }, - bases=(models.Model, utilities.tracking.TrackingModelMixin), - ), - migrations.CreateModel( - name='InterfaceTemplate', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('name', models.CharField(max_length=64)), - ('label', models.CharField(blank=True, max_length=64)), - ('description', models.CharField(blank=True, max_length=200)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize_interface)), - ('type', models.CharField(max_length=50)), - ('enabled', models.BooleanField(default=True)), - ('mgmt_only', models.BooleanField(default=False)), - ('poe_mode', models.CharField(blank=True, max_length=50)), - ('poe_type', models.CharField(blank=True, max_length=50)), - ('rf_role', models.CharField(blank=True, max_length=30)), - ], - options={ - 'verbose_name': 'interface template', - 'verbose_name_plural': 'interface templates', - 'ordering': ('device_type', 'module_type', '_name'), - 'abstract': False, - }, - bases=(models.Model, utilities.tracking.TrackingModelMixin), - ), - migrations.CreateModel( - name='InventoryItem', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=64)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), - ('label', models.CharField(blank=True, max_length=64)), - ('description', models.CharField(blank=True, max_length=200)), - ('component_id', models.PositiveBigIntegerField(blank=True, null=True)), - ('part_id', models.CharField(blank=True, max_length=50)), - ('serial', models.CharField(blank=True, max_length=50)), - ('asset_tag', models.CharField(blank=True, max_length=50, null=True, unique=True)), - ('discovered', models.BooleanField(default=False)), - ('lft', models.PositiveIntegerField(editable=False)), - ('rght', models.PositiveIntegerField(editable=False)), - ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), - ('level', models.PositiveIntegerField(editable=False)), - ], - options={ - 'verbose_name': 'inventory item', - 'verbose_name_plural': 'inventory items', - 'ordering': ('device__id', 'parent__id', '_name'), - }, - bases=(models.Model, utilities.tracking.TrackingModelMixin), - ), - migrations.CreateModel( - name='InventoryItemRole', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=100, unique=True)), - ('slug', models.SlugField(max_length=100, unique=True)), - ('description', models.CharField(blank=True, max_length=200)), - ('color', utilities.fields.ColorField(default='9e9e9e', max_length=6)), - ], - options={ - 'verbose_name': 'inventory item role', - 'verbose_name_plural': 'inventory item roles', - 'ordering': ('name',), - }, - ), - migrations.CreateModel( - name='InventoryItemTemplate', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('name', models.CharField(max_length=64)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), - ('label', models.CharField(blank=True, max_length=64)), - ('description', models.CharField(blank=True, max_length=200)), - ('component_id', models.PositiveBigIntegerField(blank=True, null=True)), - ('part_id', models.CharField(blank=True, max_length=50)), - ('lft', models.PositiveIntegerField(editable=False)), - ('rght', models.PositiveIntegerField(editable=False)), - ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), - ('level', models.PositiveIntegerField(editable=False)), - ], - options={ - 'verbose_name': 'inventory item template', - 'verbose_name_plural': 'inventory item templates', - 'ordering': ('device_type__id', 'parent__id', '_name'), - }, - bases=(models.Model, utilities.tracking.TrackingModelMixin), - ), - migrations.CreateModel( - name='Location', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=100)), - ('slug', models.SlugField(max_length=100)), - ('description', models.CharField(blank=True, max_length=200)), - ('status', models.CharField(default='active', max_length=50)), - ('lft', models.PositiveIntegerField(editable=False)), - ('rght', models.PositiveIntegerField(editable=False)), - ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), - ('level', models.PositiveIntegerField(editable=False)), - ], - options={ - 'verbose_name': 'location', - 'verbose_name_plural': 'locations', - 'ordering': ['site', 'name'], - }, - ), - migrations.CreateModel( - name='Manufacturer', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=100, unique=True)), - ('slug', models.SlugField(max_length=100, unique=True)), - ('description', models.CharField(blank=True, max_length=200)), - ], - options={ - 'verbose_name': 'manufacturer', - 'verbose_name_plural': 'manufacturers', - 'ordering': ('name',), - }, - ), - migrations.CreateModel( - name='Module', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('local_context_data', models.JSONField(blank=True, null=True)), - ('status', models.CharField(default='active', max_length=50)), - ('serial', models.CharField(blank=True, max_length=50)), - ('asset_tag', models.CharField(blank=True, max_length=50, null=True, unique=True)), - ], - options={ - 'verbose_name': 'module', - 'verbose_name_plural': 'modules', - 'ordering': ('module_bay',), - }, - ), - migrations.CreateModel( - name='ModuleBay', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=64)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), - ('label', models.CharField(blank=True, max_length=64)), - ('description', models.CharField(blank=True, max_length=200)), - ('position', models.CharField(blank=True, max_length=30)), - ], - options={ - 'verbose_name': 'module bay', - 'verbose_name_plural': 'module bays', - 'ordering': ('device', '_name'), - 'abstract': False, - }, - bases=(models.Model, utilities.tracking.TrackingModelMixin), - ), - migrations.CreateModel( - name='ModuleBayTemplate', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('name', models.CharField(max_length=64)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), - ('label', models.CharField(blank=True, max_length=64)), - ('description', models.CharField(blank=True, max_length=200)), - ('position', models.CharField(blank=True, max_length=30)), - ], - options={ - 'verbose_name': 'module bay template', - 'verbose_name_plural': 'module bay templates', - 'ordering': ('device_type', '_name'), - 'abstract': False, - }, - bases=(models.Model, utilities.tracking.TrackingModelMixin), - ), - migrations.CreateModel( - name='ModuleType', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('weight', models.DecimalField(blank=True, decimal_places=2, max_digits=8, null=True)), - ('weight_unit', models.CharField(blank=True, max_length=50)), - ('_abs_weight', models.PositiveBigIntegerField(blank=True, null=True)), - ('model', models.CharField(max_length=100)), - ('part_number', models.CharField(blank=True, max_length=50)), - ], - options={ - 'verbose_name': 'module type', - 'verbose_name_plural': 'module types', - 'ordering': ('manufacturer', 'model'), - }, - ), - migrations.CreateModel( - name='Platform', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=100, unique=True)), - ('slug', models.SlugField(max_length=100, unique=True)), - ('description', models.CharField(blank=True, max_length=200)), - ], - options={ - 'verbose_name': 'platform', - 'verbose_name_plural': 'platforms', - 'ordering': ('name',), - }, - ), - migrations.CreateModel( - name='PowerFeed', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('cable_end', models.CharField(blank=True, max_length=1)), - ('mark_connected', models.BooleanField(default=False)), - ('name', models.CharField(max_length=100)), - ('status', models.CharField(default='active', max_length=50)), - ('type', models.CharField(default='primary', max_length=50)), - ('supply', models.CharField(default='ac', max_length=50)), - ('phase', models.CharField(default='single-phase', max_length=50)), - ('voltage', models.SmallIntegerField(validators=[utilities.validators.ExclusionValidator([0])])), - ('amperage', models.PositiveSmallIntegerField(validators=[django.core.validators.MinValueValidator(1)])), - ('max_utilization', models.PositiveSmallIntegerField(validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(100)])), - ('available_power', models.PositiveIntegerField(default=0, editable=False)), - ], - options={ - 'verbose_name': 'power feed', - 'verbose_name_plural': 'power feeds', - 'ordering': ['power_panel', 'name'], - }, - ), - migrations.CreateModel( - name='PowerOutlet', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=64)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), - ('label', models.CharField(blank=True, max_length=64)), - ('description', models.CharField(blank=True, max_length=200)), - ('cable_end', models.CharField(blank=True, max_length=1)), - ('mark_connected', models.BooleanField(default=False)), - ('type', models.CharField(blank=True, max_length=50)), - ('feed_leg', models.CharField(blank=True, max_length=50)), - ], - options={ - 'verbose_name': 'power outlet', - 'verbose_name_plural': 'power outlets', - 'ordering': ('device', '_name'), - 'abstract': False, - }, - bases=(models.Model, utilities.tracking.TrackingModelMixin), - ), - migrations.CreateModel( - name='PowerOutletTemplate', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('name', models.CharField(max_length=64)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), - ('label', models.CharField(blank=True, max_length=64)), - ('description', models.CharField(blank=True, max_length=200)), - ('type', models.CharField(blank=True, max_length=50)), - ('feed_leg', models.CharField(blank=True, max_length=50)), - ], - options={ - 'verbose_name': 'power outlet template', - 'verbose_name_plural': 'power outlet templates', - 'ordering': ('device_type', 'module_type', '_name'), - 'abstract': False, - }, - bases=(models.Model, utilities.tracking.TrackingModelMixin), - ), - migrations.CreateModel( - name='PowerPanel', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('name', models.CharField(max_length=100)), - ], - options={ - 'verbose_name': 'power panel', - 'verbose_name_plural': 'power panels', - 'ordering': ['site', 'name'], - }, - ), - migrations.CreateModel( - name='PowerPort', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=64)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), - ('label', models.CharField(blank=True, max_length=64)), - ('description', models.CharField(blank=True, max_length=200)), - ('cable_end', models.CharField(blank=True, max_length=1)), - ('mark_connected', models.BooleanField(default=False)), - ('type', models.CharField(blank=True, max_length=50)), - ('maximum_draw', models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)])), - ('allocated_draw', models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)])), - ], - options={ - 'verbose_name': 'power port', - 'verbose_name_plural': 'power ports', - 'ordering': ('device', '_name'), - 'abstract': False, - }, - bases=(models.Model, utilities.tracking.TrackingModelMixin), - ), - migrations.CreateModel( - name='PowerPortTemplate', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('name', models.CharField(max_length=64)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), - ('label', models.CharField(blank=True, max_length=64)), - ('description', models.CharField(blank=True, max_length=200)), - ('type', models.CharField(blank=True, max_length=50)), - ('maximum_draw', models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)])), - ('allocated_draw', models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)])), - ], - options={ - 'verbose_name': 'power port template', - 'verbose_name_plural': 'power port templates', - 'ordering': ('device_type', 'module_type', '_name'), - 'abstract': False, - }, - bases=(models.Model, utilities.tracking.TrackingModelMixin), - ), - migrations.CreateModel( - name='Rack', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('weight', models.DecimalField(blank=True, decimal_places=2, max_digits=8, null=True)), - ('weight_unit', models.CharField(blank=True, max_length=50)), - ('_abs_weight', models.PositiveBigIntegerField(blank=True, null=True)), - ('name', models.CharField(max_length=100)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), - ('facility_id', models.CharField(blank=True, max_length=50, null=True)), - ('status', models.CharField(default='active', max_length=50)), - ('serial', models.CharField(blank=True, max_length=50)), - ('asset_tag', models.CharField(blank=True, max_length=50, null=True, unique=True)), - ('type', models.CharField(blank=True, max_length=50)), - ('width', models.PositiveSmallIntegerField(default=19)), - ('u_height', models.PositiveSmallIntegerField(default=42, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(100)])), - ('starting_unit', models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1)])), - ('desc_units', models.BooleanField(default=False)), - ('outer_width', models.PositiveSmallIntegerField(blank=True, null=True)), - ('outer_depth', models.PositiveSmallIntegerField(blank=True, null=True)), - ('outer_unit', models.CharField(blank=True, max_length=50)), - ('max_weight', models.PositiveIntegerField(blank=True, null=True)), - ('_abs_max_weight', models.PositiveBigIntegerField(blank=True, null=True)), - ('mounting_depth', models.PositiveSmallIntegerField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'rack', - 'verbose_name_plural': 'racks', - 'ordering': ('site', 'location', '_name', 'pk'), - }, - ), - migrations.CreateModel( - name='RackReservation', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('comments', models.TextField(blank=True)), - ('units', django.contrib.postgres.fields.ArrayField(base_field=models.PositiveSmallIntegerField(), size=None)), - ('description', models.CharField(max_length=200)), - ], - options={ - 'verbose_name': 'rack reservation', - 'verbose_name_plural': 'rack reservations', - 'ordering': ['created', 'pk'], - }, - ), - migrations.CreateModel( - name='RackRole', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=100, unique=True)), - ('slug', models.SlugField(max_length=100, unique=True)), - ('description', models.CharField(blank=True, max_length=200)), - ('color', utilities.fields.ColorField(default='9e9e9e', max_length=6)), - ], - options={ - 'verbose_name': 'rack role', - 'verbose_name_plural': 'rack roles', - 'ordering': ('name',), - }, - ), - migrations.CreateModel( - name='RearPort', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=64)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), - ('label', models.CharField(blank=True, max_length=64)), - ('description', models.CharField(blank=True, max_length=200)), - ('cable_end', models.CharField(blank=True, max_length=1)), - ('mark_connected', models.BooleanField(default=False)), - ('type', models.CharField(max_length=50)), - ('color', utilities.fields.ColorField(blank=True, max_length=6)), - ('positions', models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(1024)])), - ], - options={ - 'verbose_name': 'rear port', - 'verbose_name_plural': 'rear ports', - 'ordering': ('device', '_name'), - 'abstract': False, - }, - bases=(models.Model, utilities.tracking.TrackingModelMixin), - ), - migrations.CreateModel( - name='RearPortTemplate', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('name', models.CharField(max_length=64)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), - ('label', models.CharField(blank=True, max_length=64)), - ('description', models.CharField(blank=True, max_length=200)), - ('type', models.CharField(max_length=50)), - ('color', utilities.fields.ColorField(blank=True, max_length=6)), - ('positions', models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(1024)])), - ], - options={ - 'verbose_name': 'rear port template', - 'verbose_name_plural': 'rear port templates', - 'ordering': ('device_type', 'module_type', '_name'), - 'abstract': False, - }, - bases=(models.Model, utilities.tracking.TrackingModelMixin), - ), - migrations.CreateModel( - name='Region', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=100)), - ('slug', models.SlugField(max_length=100)), - ('description', models.CharField(blank=True, max_length=200)), - ('lft', models.PositiveIntegerField(editable=False)), - ('rght', models.PositiveIntegerField(editable=False)), - ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), - ('level', models.PositiveIntegerField(editable=False)), - ], - options={ - 'verbose_name': 'region', - 'verbose_name_plural': 'regions', - }, - ), - migrations.CreateModel( - name='Site', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('name', models.CharField(max_length=100, unique=True)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), - ('slug', models.SlugField(max_length=100, unique=True)), - ('status', models.CharField(default='active', max_length=50)), - ('facility', models.CharField(blank=True, max_length=50)), - ('time_zone', timezone_field.fields.TimeZoneField(blank=True)), - ('physical_address', models.CharField(blank=True, max_length=200)), - ('shipping_address', models.CharField(blank=True, max_length=200)), - ('latitude', models.DecimalField(blank=True, decimal_places=6, max_digits=8, null=True)), - ('longitude', models.DecimalField(blank=True, decimal_places=6, max_digits=9, null=True)), - ], - options={ - 'verbose_name': 'site', - 'verbose_name_plural': 'sites', - 'ordering': ('_name',), - }, - ), - migrations.CreateModel( - name='SiteGroup', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=100)), - ('slug', models.SlugField(max_length=100)), - ('description', models.CharField(blank=True, max_length=200)), - ('lft', models.PositiveIntegerField(editable=False)), - ('rght', models.PositiveIntegerField(editable=False)), - ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), - ('level', models.PositiveIntegerField(editable=False)), - ], - options={ - 'verbose_name': 'site group', - 'verbose_name_plural': 'site groups', - }, - ), - migrations.CreateModel( - name='VirtualChassis', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('name', models.CharField(max_length=64)), - ('domain', models.CharField(blank=True, max_length=30)), - ('member_count', utilities.fields.CounterCacheField(default=0, editable=False, to_field='virtual_chassis', to_model='dcim.Device')), - ], - options={ - 'verbose_name': 'virtual chassis', - 'verbose_name_plural': 'virtual chassis', - 'ordering': ['name'], - }, - ), - migrations.CreateModel( - name='VirtualDeviceContext', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('name', models.CharField(max_length=64)), - ('status', models.CharField(max_length=50)), - ('identifier', models.PositiveSmallIntegerField(blank=True, null=True)), - ('comments', models.TextField(blank=True)), - ('device', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vdcs', to='dcim.device')), - ], - options={ - 'verbose_name': 'virtual device context', - 'verbose_name_plural': 'virtual device contexts', - 'ordering': ['name'], - }, - ), - ] diff --git a/netbox/dcim/migrations/0001_squashed.py b/netbox/dcim/migrations/0001_squashed.py new file mode 100644 index 000000000..cf0ef4816 --- /dev/null +++ b/netbox/dcim/migrations/0001_squashed.py @@ -0,0 +1,664 @@ +import dcim.fields +import ipam.fields +import django.contrib.postgres.fields +from utilities.json import CustomFieldJSONEncoder +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion +import timezone_field.fields +import utilities.fields +import utilities.ordering +import utilities.query_functions +import utilities.validators + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + replaces = [ + ('dcim', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Cable', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('termination_a_id', models.PositiveIntegerField()), + ('termination_b_id', models.PositiveIntegerField()), + ('type', models.CharField(blank=True, max_length=50)), + ('status', models.CharField(default='connected', max_length=50)), + ('label', models.CharField(blank=True, max_length=100)), + ('color', utilities.fields.ColorField(blank=True, max_length=6)), + ('length', models.PositiveSmallIntegerField(blank=True, null=True)), + ('length_unit', models.CharField(blank=True, max_length=50)), + ('_abs_length', models.DecimalField(blank=True, decimal_places=4, max_digits=10, null=True)), + ], + options={ + 'ordering': ['pk'], + }, + ), + migrations.CreateModel( + name='CablePath', + fields=[ + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('origin_id', models.PositiveIntegerField()), + ('destination_id', models.PositiveIntegerField(blank=True, null=True)), + ('path', dcim.fields.PathField(base_field=models.CharField(max_length=40), size=None)), + ('is_active', models.BooleanField(default=False)), + ('is_split', models.BooleanField(default=False)), + ], + ), + migrations.CreateModel( + name='ConsolePort', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=64)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), + ('label', models.CharField(blank=True, max_length=64)), + ('description', models.CharField(blank=True, max_length=200)), + ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)), + ('mark_connected', models.BooleanField(default=False)), + ('type', models.CharField(blank=True, max_length=50)), + ('speed', models.PositiveSmallIntegerField(blank=True, null=True)), + ], + options={ + 'ordering': ('device', '_name'), + }, + ), + migrations.CreateModel( + name='ConsolePortTemplate', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=64)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), + ('label', models.CharField(blank=True, max_length=64)), + ('description', models.CharField(blank=True, max_length=200)), + ('type', models.CharField(blank=True, max_length=50)), + ], + options={ + 'ordering': ('device_type', '_name'), + }, + ), + migrations.CreateModel( + name='ConsoleServerPort', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=64)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), + ('label', models.CharField(blank=True, max_length=64)), + ('description', models.CharField(blank=True, max_length=200)), + ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)), + ('mark_connected', models.BooleanField(default=False)), + ('type', models.CharField(blank=True, max_length=50)), + ('speed', models.PositiveSmallIntegerField(blank=True, null=True)), + ], + options={ + 'ordering': ('device', '_name'), + }, + ), + migrations.CreateModel( + name='ConsoleServerPortTemplate', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=64)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), + ('label', models.CharField(blank=True, max_length=64)), + ('description', models.CharField(blank=True, max_length=200)), + ('type', models.CharField(blank=True, max_length=50)), + ], + options={ + 'ordering': ('device_type', '_name'), + }, + ), + migrations.CreateModel( + name='Device', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('local_context_data', models.JSONField(blank=True, null=True)), + ('name', models.CharField(blank=True, max_length=64, null=True)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize, null=True)), + ('serial', models.CharField(blank=True, max_length=50)), + ('asset_tag', models.CharField(blank=True, max_length=50, null=True, unique=True)), + ('position', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)])), + ('face', models.CharField(blank=True, max_length=50)), + ('status', models.CharField(default='active', max_length=50)), + ('vc_position', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(255)])), + ('vc_priority', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(255)])), + ('comments', models.TextField(blank=True)), + ], + options={ + 'ordering': ('_name', 'pk'), + }, + ), + migrations.CreateModel( + name='DeviceBay', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=64)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), + ('label', models.CharField(blank=True, max_length=64)), + ('description', models.CharField(blank=True, max_length=200)), + ], + options={ + 'ordering': ('device', '_name'), + }, + ), + migrations.CreateModel( + name='DeviceBayTemplate', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=64)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), + ('label', models.CharField(blank=True, max_length=64)), + ('description', models.CharField(blank=True, max_length=200)), + ], + options={ + 'ordering': ('device_type', '_name'), + }, + ), + migrations.CreateModel( + name='DeviceRole', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, unique=True)), + ('slug', models.SlugField(max_length=100, unique=True)), + ('color', utilities.fields.ColorField(default='9e9e9e', max_length=6)), + ('vm_role', models.BooleanField(default=True)), + ('description', models.CharField(blank=True, max_length=200)), + ], + options={ + 'ordering': ('name',), + }, + ), + migrations.CreateModel( + name='DeviceType', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('model', models.CharField(max_length=100)), + ('slug', models.SlugField(max_length=100)), + ('part_number', models.CharField(blank=True, max_length=50)), + ('u_height', models.PositiveSmallIntegerField(default=1)), + ('is_full_depth', models.BooleanField(default=True)), + ('subdevice_role', models.CharField(blank=True, max_length=50)), + ('front_image', models.ImageField(blank=True, upload_to='devicetype-images')), + ('rear_image', models.ImageField(blank=True, upload_to='devicetype-images')), + ('comments', models.TextField(blank=True)), + ], + options={ + 'ordering': ['manufacturer', 'model'], + }, + ), + migrations.CreateModel( + name='FrontPort', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=64)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), + ('label', models.CharField(blank=True, max_length=64)), + ('description', models.CharField(blank=True, max_length=200)), + ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)), + ('mark_connected', models.BooleanField(default=False)), + ('type', models.CharField(max_length=50)), + ('rear_port_position', models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(1024)])), + ], + options={ + 'ordering': ('device', '_name'), + }, + ), + migrations.CreateModel( + name='FrontPortTemplate', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=64)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), + ('label', models.CharField(blank=True, max_length=64)), + ('description', models.CharField(blank=True, max_length=200)), + ('type', models.CharField(max_length=50)), + ('rear_port_position', models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(1024)])), + ], + options={ + 'ordering': ('device_type', '_name'), + }, + ), + migrations.CreateModel( + name='Interface', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=64)), + ('label', models.CharField(blank=True, max_length=64)), + ('description', models.CharField(blank=True, max_length=200)), + ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)), + ('mark_connected', models.BooleanField(default=False)), + ('enabled', models.BooleanField(default=True)), + ('mac_address', dcim.fields.MACAddressField(blank=True, null=True)), + ('mtu', models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(65536)])), + ('mode', models.CharField(blank=True, max_length=50)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize_interface)), + ('type', models.CharField(max_length=50)), + ('mgmt_only', models.BooleanField(default=False)), + ], + options={ + 'ordering': ('device', utilities.query_functions.CollateAsChar('_name')), + }, + ), + migrations.CreateModel( + name='InterfaceTemplate', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=64)), + ('label', models.CharField(blank=True, max_length=64)), + ('description', models.CharField(blank=True, max_length=200)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize_interface)), + ('type', models.CharField(max_length=50)), + ('mgmt_only', models.BooleanField(default=False)), + ], + options={ + 'ordering': ('device_type', '_name'), + }, + ), + migrations.CreateModel( + name='InventoryItem', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=64)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), + ('label', models.CharField(blank=True, max_length=64)), + ('description', models.CharField(blank=True, max_length=200)), + ('part_id', models.CharField(blank=True, max_length=50)), + ('serial', models.CharField(blank=True, max_length=50)), + ('asset_tag', models.CharField(blank=True, max_length=50, null=True, unique=True)), + ('discovered', models.BooleanField(default=False)), + ('lft', models.PositiveIntegerField(editable=False)), + ('rght', models.PositiveIntegerField(editable=False)), + ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), + ('level', models.PositiveIntegerField(editable=False)), + ], + options={ + 'ordering': ('device__id', 'parent__id', '_name'), + }, + ), + migrations.CreateModel( + name='Location', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100)), + ('slug', models.SlugField(max_length=100)), + ('description', models.CharField(blank=True, max_length=200)), + ('lft', models.PositiveIntegerField(editable=False)), + ('rght', models.PositiveIntegerField(editable=False)), + ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), + ('level', models.PositiveIntegerField(editable=False)), + ], + options={ + 'ordering': ['site', 'name'], + }, + ), + migrations.CreateModel( + name='Manufacturer', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, unique=True)), + ('slug', models.SlugField(max_length=100, unique=True)), + ('description', models.CharField(blank=True, max_length=200)), + ], + options={ + 'ordering': ('name',), + }, + ), + migrations.CreateModel( + name='Platform', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, unique=True)), + ('slug', models.SlugField(max_length=100, unique=True)), + ('napalm_driver', models.CharField(blank=True, max_length=50)), + ('napalm_args', models.JSONField(blank=True, null=True)), + ('description', models.CharField(blank=True, max_length=200)), + ], + options={ + 'ordering': ('name',), + }, + ), + migrations.CreateModel( + name='PowerFeed', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)), + ('mark_connected', models.BooleanField(default=False)), + ('name', models.CharField(max_length=100)), + ('status', models.CharField(default='active', max_length=50)), + ('type', models.CharField(default='primary', max_length=50)), + ('supply', models.CharField(default='ac', max_length=50)), + ('phase', models.CharField(default='single-phase', max_length=50)), + ('voltage', models.SmallIntegerField(validators=[utilities.validators.ExclusionValidator([0])])), + ('amperage', models.PositiveSmallIntegerField(validators=[django.core.validators.MinValueValidator(1)])), + ('max_utilization', models.PositiveSmallIntegerField(validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(100)])), + ('available_power', models.PositiveIntegerField(default=0, editable=False)), + ('comments', models.TextField(blank=True)), + ], + options={ + 'ordering': ['power_panel', 'name'], + }, + ), + migrations.CreateModel( + name='PowerOutlet', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=64)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), + ('label', models.CharField(blank=True, max_length=64)), + ('description', models.CharField(blank=True, max_length=200)), + ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)), + ('mark_connected', models.BooleanField(default=False)), + ('type', models.CharField(blank=True, max_length=50)), + ('feed_leg', models.CharField(blank=True, max_length=50)), + ], + options={ + 'ordering': ('device', '_name'), + }, + ), + migrations.CreateModel( + name='PowerOutletTemplate', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=64)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), + ('label', models.CharField(blank=True, max_length=64)), + ('description', models.CharField(blank=True, max_length=200)), + ('type', models.CharField(blank=True, max_length=50)), + ('feed_leg', models.CharField(blank=True, max_length=50)), + ], + options={ + 'ordering': ('device_type', '_name'), + }, + ), + migrations.CreateModel( + name='PowerPanel', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100)), + ], + options={ + 'ordering': ['site', 'name'], + }, + ), + migrations.CreateModel( + name='PowerPort', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=64)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), + ('label', models.CharField(blank=True, max_length=64)), + ('description', models.CharField(blank=True, max_length=200)), + ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)), + ('mark_connected', models.BooleanField(default=False)), + ('type', models.CharField(blank=True, max_length=50)), + ('maximum_draw', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)])), + ('allocated_draw', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)])), + ], + options={ + 'ordering': ('device', '_name'), + }, + ), + migrations.CreateModel( + name='PowerPortTemplate', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=64)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), + ('label', models.CharField(blank=True, max_length=64)), + ('description', models.CharField(blank=True, max_length=200)), + ('type', models.CharField(blank=True, max_length=50)), + ('maximum_draw', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)])), + ('allocated_draw', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)])), + ], + options={ + 'ordering': ('device_type', '_name'), + }, + ), + migrations.CreateModel( + name='Rack', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), + ('facility_id', models.CharField(blank=True, max_length=50, null=True)), + ('status', models.CharField(default='active', max_length=50)), + ('serial', models.CharField(blank=True, max_length=50)), + ('asset_tag', models.CharField(blank=True, max_length=50, null=True, unique=True)), + ('type', models.CharField(blank=True, max_length=50)), + ('width', models.PositiveSmallIntegerField(default=19)), + ('u_height', models.PositiveSmallIntegerField(default=42, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(100)])), + ('desc_units', models.BooleanField(default=False)), + ('outer_width', models.PositiveSmallIntegerField(blank=True, null=True)), + ('outer_depth', models.PositiveSmallIntegerField(blank=True, null=True)), + ('outer_unit', models.CharField(blank=True, max_length=50)), + ('comments', models.TextField(blank=True)), + ], + options={ + 'ordering': ('site', 'location', '_name', 'pk'), + }, + ), + migrations.CreateModel( + name='RackReservation', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('units', django.contrib.postgres.fields.ArrayField(base_field=models.PositiveSmallIntegerField(), size=None)), + ('description', models.CharField(max_length=200)), + ], + options={ + 'ordering': ['created', 'pk'], + }, + ), + migrations.CreateModel( + name='RackRole', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, unique=True)), + ('slug', models.SlugField(max_length=100, unique=True)), + ('color', utilities.fields.ColorField(default='9e9e9e', max_length=6)), + ('description', models.CharField(blank=True, max_length=200)), + ], + options={ + 'ordering': ('name',), + }, + ), + migrations.CreateModel( + name='RearPort', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=64)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), + ('label', models.CharField(blank=True, max_length=64)), + ('description', models.CharField(blank=True, max_length=200)), + ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)), + ('mark_connected', models.BooleanField(default=False)), + ('type', models.CharField(max_length=50)), + ('positions', models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(1024)])), + ], + options={ + 'ordering': ('device', '_name'), + }, + ), + migrations.CreateModel( + name='RearPortTemplate', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=64)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), + ('label', models.CharField(blank=True, max_length=64)), + ('description', models.CharField(blank=True, max_length=200)), + ('type', models.CharField(max_length=50)), + ('positions', models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(1024)])), + ], + options={ + 'ordering': ('device_type', '_name'), + }, + ), + migrations.CreateModel( + name='Region', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, unique=True)), + ('slug', models.SlugField(max_length=100, unique=True)), + ('description', models.CharField(blank=True, max_length=200)), + ('lft', models.PositiveIntegerField(editable=False)), + ('rght', models.PositiveIntegerField(editable=False)), + ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), + ('level', models.PositiveIntegerField(editable=False)), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='Site', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, unique=True)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), + ('slug', models.SlugField(max_length=100, unique=True)), + ('status', models.CharField(default='active', max_length=50)), + ('facility', models.CharField(blank=True, max_length=50)), + ('asn', ipam.fields.ASNField(blank=True, null=True)), + ('time_zone', timezone_field.fields.TimeZoneField(blank=True)), + ('description', models.CharField(blank=True, max_length=200)), + ('physical_address', models.CharField(blank=True, max_length=200)), + ('shipping_address', models.CharField(blank=True, max_length=200)), + ('latitude', models.DecimalField(blank=True, decimal_places=6, max_digits=8, null=True)), + ('longitude', models.DecimalField(blank=True, decimal_places=6, max_digits=9, null=True)), + ('contact_name', models.CharField(blank=True, max_length=50)), + ('contact_phone', models.CharField(blank=True, max_length=20)), + ('contact_email', models.EmailField(blank=True, max_length=254)), + ('comments', models.TextField(blank=True)), + ], + options={ + 'ordering': ('_name',), + }, + ), + migrations.CreateModel( + name='SiteGroup', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, unique=True)), + ('slug', models.SlugField(max_length=100, unique=True)), + ('description', models.CharField(blank=True, max_length=200)), + ('lft', models.PositiveIntegerField(editable=False)), + ('rght', models.PositiveIntegerField(editable=False)), + ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), + ('level', models.PositiveIntegerField(editable=False)), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='VirtualChassis', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=64)), + ('domain', models.CharField(blank=True, max_length=30)), + ('master', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vc_master_for', to='dcim.device')), + ], + options={ + 'verbose_name_plural': 'virtual chassis', + 'ordering': ['name'], + }, + ), + ] diff --git a/netbox/dcim/migrations/0002_squashed.py b/netbox/dcim/migrations/0002_squashed.py index 06f607de1..c7325210e 100644 --- a/netbox/dcim/migrations/0002_squashed.py +++ b/netbox/dcim/migrations/0002_squashed.py @@ -1,16 +1,18 @@ +from django.conf import settings from django.db import migrations, models import django.db.models.deletion +import mptt.fields import taggit.managers class Migration(migrations.Migration): - initial = True - dependencies = [ - ('extras', '0001_initial'), - ('ipam', '0001_initial'), ('dcim', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('contenttypes', '0002_remove_content_type_name'), + ('extras', '0001_initial'), + ('tenancy', '0001_initial'), ] replaces = [ @@ -19,18 +21,293 @@ class Migration(migrations.Migration): operations = [ migrations.AddField( - model_name='virtualdevicecontext', - name='primary_ip4', - field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='ipam.ipaddress'), - ), - migrations.AddField( - model_name='virtualdevicecontext', - name='primary_ip6', - field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='ipam.ipaddress'), - ), - migrations.AddField( - model_name='virtualdevicecontext', + model_name='virtualchassis', name='tags', field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), ), + migrations.AddField( + model_name='sitegroup', + name='parent', + field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='dcim.sitegroup'), + ), + migrations.AddField( + model_name='site', + name='group', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sites', to='dcim.sitegroup'), + ), + migrations.AddField( + model_name='site', + name='region', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sites', to='dcim.region'), + ), + migrations.AddField( + model_name='site', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='site', + name='tenant', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='sites', to='tenancy.tenant'), + ), + migrations.AddField( + model_name='region', + name='parent', + field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='dcim.region'), + ), + migrations.AddField( + model_name='rearporttemplate', + name='device_type', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), + ), + migrations.AddField( + model_name='rearport', + name='_cable_peer_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'), + ), + migrations.AddField( + model_name='rearport', + name='cable', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'), + ), + migrations.AddField( + model_name='rearport', + name='device', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'), + ), + migrations.AddField( + model_name='rearport', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='rackreservation', + name='rack', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reservations', to='dcim.rack'), + ), + migrations.AddField( + model_name='rackreservation', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='rackreservation', + name='tenant', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='rackreservations', to='tenancy.tenant'), + ), + migrations.AddField( + model_name='rackreservation', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='rack', + name='location', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='racks', to='dcim.location'), + ), + migrations.AddField( + model_name='rack', + name='role', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='racks', to='dcim.rackrole'), + ), + migrations.AddField( + model_name='rack', + name='site', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='racks', to='dcim.site'), + ), + migrations.AddField( + model_name='rack', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='rack', + name='tenant', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='racks', to='tenancy.tenant'), + ), + migrations.AddField( + model_name='powerporttemplate', + name='device_type', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), + ), + migrations.AddField( + model_name='powerport', + name='_cable_peer_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'), + ), + migrations.AddField( + model_name='powerport', + name='_path', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'), + ), + migrations.AddField( + model_name='powerport', + name='cable', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'), + ), + migrations.AddField( + model_name='powerport', + name='device', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'), + ), + migrations.AddField( + model_name='powerport', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='powerpanel', + name='location', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='dcim.location'), + ), + migrations.AddField( + model_name='powerpanel', + name='site', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='dcim.site'), + ), + migrations.AddField( + model_name='powerpanel', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='poweroutlettemplate', + name='device_type', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), + ), + migrations.AddField( + model_name='poweroutlettemplate', + name='power_port', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='poweroutlet_templates', to='dcim.powerporttemplate'), + ), + migrations.AddField( + model_name='poweroutlet', + name='_cable_peer_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'), + ), + migrations.AddField( + model_name='poweroutlet', + name='_path', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'), + ), + migrations.AddField( + model_name='poweroutlet', + name='cable', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'), + ), + migrations.AddField( + model_name='poweroutlet', + name='device', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'), + ), + migrations.AddField( + model_name='poweroutlet', + name='power_port', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='poweroutlets', to='dcim.powerport'), + ), + migrations.AddField( + model_name='poweroutlet', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='powerfeed', + name='_cable_peer_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'), + ), + migrations.AddField( + model_name='powerfeed', + name='_path', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'), + ), + migrations.AddField( + model_name='powerfeed', + name='cable', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'), + ), + migrations.AddField( + model_name='powerfeed', + name='power_panel', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='powerfeeds', to='dcim.powerpanel'), + ), + migrations.AddField( + model_name='powerfeed', + name='rack', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='dcim.rack'), + ), + migrations.AddField( + model_name='powerfeed', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='platform', + name='manufacturer', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='platforms', to='dcim.manufacturer'), + ), + migrations.AddField( + model_name='location', + name='parent', + field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='dcim.location'), + ), + migrations.AddField( + model_name='location', + name='site', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='locations', to='dcim.site'), + ), + migrations.AddField( + model_name='inventoryitem', + name='device', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'), + ), + migrations.AddField( + model_name='inventoryitem', + name='manufacturer', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='inventory_items', to='dcim.manufacturer'), + ), + migrations.AddField( + model_name='inventoryitem', + name='parent', + field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='child_items', to='dcim.inventoryitem'), + ), + migrations.AddField( + model_name='inventoryitem', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='interfacetemplate', + name='device_type', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), + ), + migrations.AddField( + model_name='interface', + name='_cable_peer_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'), + ), + migrations.AddField( + model_name='interface', + name='_path', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'), + ), + migrations.AddField( + model_name='interface', + name='cable', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'), + ), + migrations.AddField( + model_name='interface', + name='device', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'), + ), + migrations.AddField( + model_name='interface', + name='lag', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='member_interfaces', to='dcim.interface'), + ), + migrations.AddField( + model_name='interface', + name='parent', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='child_interfaces', to='dcim.interface'), + ), ] diff --git a/netbox/dcim/migrations/0003_squashed.py b/netbox/dcim/migrations/0003_squashed.py deleted file mode 100644 index ee40e9939..000000000 --- a/netbox/dcim/migrations/0003_squashed.py +++ /dev/null @@ -1,1190 +0,0 @@ -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion -import django.db.models.functions.text -import mptt.fields -import taggit.managers - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ('extras', '0001_initial'), - ('virtualization', '0001_initial'), - ('contenttypes', '0002_remove_content_type_name'), - ('dcim', '0002_squashed'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('ipam', '0001_initial'), - ('wireless', '0001_initial'), - ('tenancy', '0001_initial'), - ] - - replaces = [ - ('dcim', '0003_auto_20160628_1721'), - ('dcim', '0004_auto_20160701_2049'), - ('dcim', '0005_auto_20160706_1722'), - ('dcim', '0006_add_device_primary_ip4_ip6'), - ('dcim', '0007_device_copy_primary_ip'), - ('dcim', '0008_device_remove_primary_ip'), - ('dcim', '0009_site_32bit_asn_support'), - ('dcim', '0010_devicebay_installed_device_set_null'), - ('dcim', '0011_devicetype_part_number'), - ('dcim', '0012_site_rack_device_add_tenant'), - ('dcim', '0013_add_interface_form_factors'), - ('dcim', '0014_rack_add_type_width'), - ('dcim', '0015_rack_add_u_height_validator'), - ('dcim', '0016_module_add_manufacturer'), - ('dcim', '0017_rack_add_role'), - ('dcim', '0018_device_add_asset_tag'), - ('dcim', '0019_new_iface_form_factors'), - ('dcim', '0020_rack_desc_units'), - ('dcim', '0021_add_ff_flexstack'), - ('dcim', '0022_color_names_to_rgb'), - ('dcim', '0023_devicetype_comments'), - ('dcim', '0024_site_add_contact_fields'), - ('dcim', '0025_devicetype_add_interface_ordering'), - ('dcim', '0026_add_rack_reservations'), - ('dcim', '0027_device_add_site'), - ('dcim', '0028_device_copy_rack_to_site'), - ('dcim', '0029_allow_rackless_devices'), - ('dcim', '0030_interface_add_lag'), - ('dcim', '0031_regions'), - ('dcim', '0032_device_increase_name_length'), - ('dcim', '0033_rackreservation_rack_editable'), - ('dcim', '0034_rename_module_to_inventoryitem'), - ('dcim', '0035_device_expand_status_choices'), - ('dcim', '0036_add_ff_juniper_vcp'), - ('dcim', '0037_unicode_literals'), - ('dcim', '0038_wireless_interfaces'), - ('dcim', '0039_interface_add_enabled_mtu'), - ('dcim', '0040_inventoryitem_add_asset_tag_description'), - ('dcim', '0041_napalm_integration'), - ('dcim', '0042_interface_ff_10ge_cx4'), - ('dcim', '0043_device_component_name_lengths'), - ('dcim', '0044_virtualization'), - ('dcim', '0045_devicerole_vm_role'), - ('dcim', '0046_rack_lengthen_facility_id'), - ('dcim', '0047_more_100ge_form_factors'), - ('dcim', '0048_rack_serial'), - ('dcim', '0049_rackreservation_change_user'), - ('dcim', '0050_interface_vlan_tagging'), - ('dcim', '0051_rackreservation_tenant'), - ('dcim', '0052_virtual_chassis'), - ('dcim', '0053_platform_manufacturer'), - ('dcim', '0054_site_status_timezone_description'), - ('dcim', '0055_virtualchassis_ordering'), - ('dcim', '0056_django2'), - ('dcim', '0057_tags'), - ('dcim', '0058_relax_rack_naming_constraints'), - ('dcim', '0059_site_latitude_longitude'), - ('dcim', '0060_change_logging'), - ('dcim', '0061_platform_napalm_args'), - ('dcim', '0062_interface_mtu'), - ('dcim', '0063_device_local_context_data'), - ('dcim', '0064_remove_platform_rpc_client'), - ('dcim', '0065_front_rear_ports'), - ('dcim', '0066_cables'), - ('dcim', '0067_device_type_remove_qualifiers'), - ('dcim', '0068_rack_new_fields'), - ('dcim', '0069_deprecate_nullablecharfield'), - ('dcim', '0070_custom_tag_models'), - ('dcim', '0071_device_components_add_description'), - ('dcim', '0072_powerfeeds'), - ('dcim', '0073_interface_form_factor_to_type'), - ('dcim', '0074_increase_field_length_platform_name_slug'), - ('dcim', '0075_cable_devices'), - ('dcim', '0076_console_port_types'), - ('dcim', '0077_power_types'), - ('dcim', '0078_3569_site_fields'), - ('dcim', '0079_3569_rack_fields'), - ('dcim', '0080_3569_devicetype_fields'), - ('dcim', '0081_3569_device_fields'), - ('dcim', '0082_3569_interface_fields'), - ('dcim', '0082_3569_port_fields'), - ('dcim', '0083_3569_cable_fields'), - ('dcim', '0084_3569_powerfeed_fields'), - ('dcim', '0085_3569_poweroutlet_fields'), - ('dcim', '0086_device_name_nonunique'), - ('dcim', '0087_role_descriptions'), - ('dcim', '0088_powerfeed_available_power'), - ('dcim', '0089_deterministic_ordering'), - ('dcim', '0090_cable_termination_models'), - ('dcim', '0091_interface_type_other'), - ('dcim', '0092_fix_rack_outer_unit'), - ('dcim', '0093_device_component_ordering'), - ('dcim', '0094_device_component_template_ordering'), - ('dcim', '0095_primary_model_ordering'), - ('dcim', '0096_interface_ordering'), - ('dcim', '0097_interfacetemplate_type_other'), - ('dcim', '0098_devicetype_images'), - ('dcim', '0099_powerfeed_negative_voltage'), - ('dcim', '0100_mptt_remove_indexes'), - ('dcim', '0101_nested_rackgroups'), - ('dcim', '0102_nested_rackgroups_rebuild'), - ('dcim', '0103_standardize_description'), - ('dcim', '0104_correct_infiniband_types'), - ('dcim', '0105_interface_name_collation'), - ('dcim', '0106_role_default_color'), - ('dcim', '0107_component_labels'), - ('dcim', '0108_add_tags'), - ('dcim', '0109_interface_remove_vm'), - ('dcim', '0110_virtualchassis_name'), - ('dcim', '0111_component_template_description'), - ('dcim', '0112_standardize_components'), - ('dcim', '0113_nullbooleanfield_to_booleanfield'), - ('dcim', '0114_update_jsonfield'), - ('dcim', '0115_rackreservation_order'), - ('dcim', '0116_rearport_max_positions'), - ('dcim', '0117_custom_field_data'), - ('dcim', '0118_inventoryitem_mptt'), - ('dcim', '0119_inventoryitem_mptt_rebuild'), - ('dcim', '0120_cache_cable_peer'), - ('dcim', '0121_cablepath'), - ('dcim', '0122_standardize_name_length'), - ('dcim', '0123_standardize_models'), - ('dcim', '0124_mark_connected'), - ('dcim', '0125_console_port_speed'), - ('dcim', '0126_rename_rackgroup_location'), - ('dcim', '0127_device_location'), - ('dcim', '0128_device_location_populate'), - ('dcim', '0129_interface_parent'), - ('dcim', '0130_sitegroup'), - ('dcim', '0131_consoleport_speed'), - ('dcim', '0132_cable_length'), - ('dcim', '0133_port_colors'), - ('dcim', '0134_interface_wwn_bridge'), - ('dcim', '0135_tenancy_extensions'), - ('dcim', '0136_device_airflow'), - ('dcim', '0137_relax_uniqueness_constraints'), - ('dcim', '0138_extend_tag_support'), - ('dcim', '0139_rename_cable_peer'), - ('dcim', '0140_wireless'), - ('dcim', '0141_asn_model'), - ('dcim', '0142_rename_128gfc_qsfp28'), - ('dcim', '0143_remove_primary_for_related_name'), - ('dcim', '0144_fix_cable_abs_length'), - ('dcim', '0145_site_remove_deprecated_fields'), - ('dcim', '0146_modules'), - ('dcim', '0147_inventoryitemrole'), - ('dcim', '0148_inventoryitem_component'), - ('dcim', '0149_inventoryitem_templates'), - ('dcim', '0150_interface_vrf'), - ('dcim', '0151_interface_speed_duplex'), - ('dcim', '0152_standardize_id_fields'), - ('dcim', '0153_created_datetimefield'), - ('dcim', '0154_half_height_rack_units'), - ('dcim', '0155_interface_poe_mode_type'), - ('dcim', '0156_location_status'), - ('dcim', '0157_new_cabling_models'), - ('dcim', '0158_populate_cable_terminations'), - ('dcim', '0159_populate_cable_paths'), - ('dcim', '0160_populate_cable_ends'), - ('dcim', '0161_cabling_cleanup'), - ('dcim', '0162_unique_constraints'), - ('dcim', '0163_weight_fields'), - ('dcim', '0164_rack_mounting_depth'), - ('dcim', '0165_standardize_description_comments'), - ('dcim', '0166_virtualdevicecontext'), - ('dcim', '0167_module_status'), - ('dcim', '0168_interface_template_enabled'), - ('dcim', '0169_devicetype_default_platform'), - ('dcim', '0170_configtemplate'), - ('dcim', '0171_cabletermination_change_logging'), - ('dcim', '0172_larger_power_draw_values'), - ('dcim', '0173_remove_napalm_fields'), - ('dcim', '0174_device_latitude_device_longitude'), - ('dcim', '0174_rack_starting_unit'), # Duplicate number - ('dcim', '0175_device_oob_ip'), - ('dcim', '0176_device_component_counters'), - ('dcim', '0177_devicetype_component_counters'), - ('dcim', '0178_virtual_chassis_member_counter'), - ('dcim', '0179_interfacetemplate_rf_role'), - ('dcim', '0180_powerfeed_tenant'), - ('dcim', '0181_rename_device_role_device_role'), - ('dcim', '0182_zero_length_cable_fix'), - ] - - operations = [ - migrations.AddField( - model_name='virtualdevicecontext', - name='tenant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vdcs', to='tenancy.tenant'), - ), - migrations.AddField( - model_name='virtualchassis', - name='master', - field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vc_master_for', to='dcim.device'), - ), - migrations.AddField( - model_name='virtualchassis', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='sitegroup', - name='parent', - field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='dcim.sitegroup'), - ), - migrations.AddField( - model_name='sitegroup', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='site', - name='asns', - field=models.ManyToManyField(blank=True, related_name='sites', to='ipam.asn'), - ), - migrations.AddField( - model_name='site', - name='group', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sites', to='dcim.sitegroup'), - ), - migrations.AddField( - model_name='site', - name='region', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sites', to='dcim.region'), - ), - migrations.AddField( - model_name='site', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='site', - name='tenant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='sites', to='tenancy.tenant'), - ), - migrations.AddField( - model_name='region', - name='parent', - field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='dcim.region'), - ), - migrations.AddField( - model_name='region', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='rearporttemplate', - name='device_type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), - ), - migrations.AddField( - model_name='rearporttemplate', - name='module_type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'), - ), - migrations.AddField( - model_name='rearport', - name='cable', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'), - ), - migrations.AddField( - model_name='rearport', - name='device', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'), - ), - migrations.AddField( - model_name='rearport', - name='module', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.module'), - ), - migrations.AddField( - model_name='rearport', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='rackrole', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='rackreservation', - name='rack', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reservations', to='dcim.rack'), - ), - migrations.AddField( - model_name='rackreservation', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='rackreservation', - name='tenant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='rackreservations', to='tenancy.tenant'), - ), - migrations.AddField( - model_name='rackreservation', - name='user', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL), - ), - migrations.AddField( - model_name='rack', - name='location', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='racks', to='dcim.location'), - ), - migrations.AddField( - model_name='rack', - name='role', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='racks', to='dcim.rackrole'), - ), - migrations.AddField( - model_name='rack', - name='site', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='racks', to='dcim.site'), - ), - migrations.AddField( - model_name='rack', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='rack', - name='tenant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='racks', to='tenancy.tenant'), - ), - migrations.AddField( - model_name='powerporttemplate', - name='device_type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), - ), - migrations.AddField( - model_name='powerporttemplate', - name='module_type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'), - ), - migrations.AddField( - model_name='powerport', - name='_path', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'), - ), - migrations.AddField( - model_name='powerport', - name='cable', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'), - ), - migrations.AddField( - model_name='powerport', - name='device', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'), - ), - migrations.AddField( - model_name='powerport', - name='module', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.module'), - ), - migrations.AddField( - model_name='powerport', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='powerpanel', - name='location', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='dcim.location'), - ), - migrations.AddField( - model_name='powerpanel', - name='site', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='dcim.site'), - ), - migrations.AddField( - model_name='powerpanel', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='poweroutlettemplate', - name='device_type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), - ), - migrations.AddField( - model_name='poweroutlettemplate', - name='module_type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'), - ), - migrations.AddField( - model_name='poweroutlettemplate', - name='power_port', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='poweroutlet_templates', to='dcim.powerporttemplate'), - ), - migrations.AddField( - model_name='poweroutlet', - name='_path', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'), - ), - migrations.AddField( - model_name='poweroutlet', - name='cable', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'), - ), - migrations.AddField( - model_name='poweroutlet', - name='device', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'), - ), - migrations.AddField( - model_name='poweroutlet', - name='module', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.module'), - ), - migrations.AddField( - model_name='poweroutlet', - name='power_port', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='poweroutlets', to='dcim.powerport'), - ), - migrations.AddField( - model_name='poweroutlet', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='powerfeed', - name='_path', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'), - ), - migrations.AddField( - model_name='powerfeed', - name='cable', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'), - ), - migrations.AddField( - model_name='powerfeed', - name='power_panel', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='powerfeeds', to='dcim.powerpanel'), - ), - migrations.AddField( - model_name='powerfeed', - name='rack', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='dcim.rack'), - ), - migrations.AddField( - model_name='powerfeed', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='powerfeed', - name='tenant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='power_feeds', to='tenancy.tenant'), - ), - migrations.AddField( - model_name='platform', - name='config_template', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='platforms', to='extras.configtemplate'), - ), - migrations.AddField( - model_name='platform', - name='manufacturer', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='platforms', to='dcim.manufacturer'), - ), - migrations.AddField( - model_name='platform', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='moduletype', - name='manufacturer', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='module_types', to='dcim.manufacturer'), - ), - migrations.AddField( - model_name='moduletype', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='modulebaytemplate', - name='device_type', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), - ), - migrations.AddField( - model_name='modulebay', - name='device', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'), - ), - migrations.AddField( - model_name='modulebay', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='module', - name='device', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='modules', to='dcim.device'), - ), - migrations.AddField( - model_name='module', - name='module_bay', - field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='installed_module', to='dcim.modulebay'), - ), - migrations.AddField( - model_name='module', - name='module_type', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='instances', to='dcim.moduletype'), - ), - migrations.AddField( - model_name='module', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='manufacturer', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='location', - name='parent', - field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='dcim.location'), - ), - migrations.AddField( - model_name='location', - name='site', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='locations', to='dcim.site'), - ), - migrations.AddField( - model_name='location', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='location', - name='tenant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='locations', to='tenancy.tenant'), - ), - migrations.AddField( - model_name='inventoryitemtemplate', - name='component_type', - field=models.ForeignKey(blank=True, limit_choices_to=models.Q(('app_label', 'dcim'), ('model__in', ('consoleporttemplate', 'consoleserverporttemplate', 'frontporttemplate', 'interfacetemplate', 'poweroutlettemplate', 'powerporttemplate', 'rearporttemplate'))), null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype'), - ), - migrations.AddField( - model_name='inventoryitemtemplate', - name='device_type', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), - ), - migrations.AddField( - model_name='inventoryitemtemplate', - name='manufacturer', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='inventory_item_templates', to='dcim.manufacturer'), - ), - migrations.AddField( - model_name='inventoryitemtemplate', - name='parent', - field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='child_items', to='dcim.inventoryitemtemplate'), - ), - migrations.AddField( - model_name='inventoryitemtemplate', - name='role', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='inventory_item_templates', to='dcim.inventoryitemrole'), - ), - migrations.AddField( - model_name='inventoryitemrole', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='inventoryitem', - name='component_type', - field=models.ForeignKey(blank=True, limit_choices_to=models.Q(('app_label', 'dcim'), ('model__in', ('consoleport', 'consoleserverport', 'frontport', 'interface', 'poweroutlet', 'powerport', 'rearport'))), null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype'), - ), - migrations.AddField( - model_name='inventoryitem', - name='device', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'), - ), - migrations.AddField( - model_name='inventoryitem', - name='manufacturer', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='inventory_items', to='dcim.manufacturer'), - ), - migrations.AddField( - model_name='inventoryitem', - name='parent', - field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='child_items', to='dcim.inventoryitem'), - ), - migrations.AddField( - model_name='inventoryitem', - name='role', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='inventory_items', to='dcim.inventoryitemrole'), - ), - migrations.AddField( - model_name='inventoryitem', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='interfacetemplate', - name='bridge', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='bridge_interfaces', to='dcim.interfacetemplate'), - ), - migrations.AddField( - model_name='interfacetemplate', - name='device_type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), - ), - migrations.AddField( - model_name='interfacetemplate', - name='module_type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'), - ), - migrations.AddField( - model_name='interface', - name='_path', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'), - ), - migrations.AddField( - model_name='interface', - name='bridge', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='bridge_interfaces', to='dcim.interface'), - ), - migrations.AddField( - model_name='interface', - name='cable', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'), - ), - migrations.AddField( - model_name='interface', - name='device', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'), - ), - migrations.AddField( - model_name='interface', - name='lag', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='member_interfaces', to='dcim.interface'), - ), - migrations.AddField( - model_name='interface', - name='module', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.module'), - ), - migrations.AddField( - model_name='interface', - name='parent', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='child_interfaces', to='dcim.interface'), - ), - migrations.AddField( - model_name='interface', - name='tagged_vlans', - field=models.ManyToManyField(blank=True, related_name='interfaces_as_tagged', to='ipam.vlan'), - ), - migrations.AddField( - model_name='interface', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='interface', - name='untagged_vlan', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='interfaces_as_untagged', to='ipam.vlan'), - ), - migrations.AddField( - model_name='interface', - name='vdcs', - field=models.ManyToManyField(related_name='interfaces', to='dcim.virtualdevicecontext'), - ), - migrations.AddField( - model_name='interface', - name='vrf', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='interfaces', to='ipam.vrf'), - ), - migrations.AddField( - model_name='interface', - name='wireless_lans', - field=models.ManyToManyField(blank=True, related_name='interfaces', to='wireless.wirelesslan'), - ), - migrations.AddField( - model_name='interface', - name='wireless_link', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wireless.wirelesslink'), - ), - migrations.AddField( - model_name='frontporttemplate', - name='device_type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), - ), - migrations.AddField( - model_name='frontporttemplate', - name='module_type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'), - ), - migrations.AddField( - model_name='frontporttemplate', - name='rear_port', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='frontport_templates', to='dcim.rearporttemplate'), - ), - migrations.AddField( - model_name='frontport', - name='cable', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'), - ), - migrations.AddField( - model_name='frontport', - name='device', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'), - ), - migrations.AddField( - model_name='frontport', - name='module', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.module'), - ), - migrations.AddField( - model_name='frontport', - name='rear_port', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='frontports', to='dcim.rearport'), - ), - migrations.AddField( - model_name='frontport', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='devicetype', - name='default_platform', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.platform'), - ), - migrations.AddField( - model_name='devicetype', - name='manufacturer', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='device_types', to='dcim.manufacturer'), - ), - migrations.AddField( - model_name='devicetype', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='devicerole', - name='config_template', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='device_roles', to='extras.configtemplate'), - ), - migrations.AddField( - model_name='devicerole', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='devicebaytemplate', - name='device_type', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), - ), - migrations.AddField( - model_name='devicebay', - name='device', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'), - ), - migrations.AddField( - model_name='devicebay', - name='installed_device', - field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='parent_bay', to='dcim.device'), - ), - migrations.AddField( - model_name='devicebay', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='device', - name='cluster', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='devices', to='virtualization.cluster'), - ), - migrations.AddField( - model_name='device', - name='config_template', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='%(class)ss', to='extras.configtemplate'), - ), - migrations.AddField( - model_name='device', - name='device_type', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='instances', to='dcim.devicetype'), - ), - migrations.AddField( - model_name='device', - name='location', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='dcim.location'), - ), - migrations.AddField( - model_name='device', - name='oob_ip', - field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='ipam.ipaddress'), - ), - migrations.AddField( - model_name='device', - name='platform', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='devices', to='dcim.platform'), - ), - migrations.AddField( - model_name='device', - name='primary_ip4', - field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='ipam.ipaddress'), - ), - migrations.AddField( - model_name='device', - name='primary_ip6', - field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='ipam.ipaddress'), - ), - migrations.AddField( - model_name='device', - name='rack', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='dcim.rack'), - ), - migrations.AddField( - model_name='device', - name='role', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='dcim.devicerole'), - ), - migrations.AddField( - model_name='device', - name='site', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='dcim.site'), - ), - migrations.AddField( - model_name='device', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='device', - name='tenant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='tenancy.tenant'), - ), - migrations.AddField( - model_name='device', - name='virtual_chassis', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='members', to='dcim.virtualchassis'), - ), - migrations.AddField( - model_name='consoleserverporttemplate', - name='device_type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), - ), - migrations.AddField( - model_name='consoleserverporttemplate', - name='module_type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'), - ), - migrations.AddField( - model_name='consoleserverport', - name='_path', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'), - ), - migrations.AddField( - model_name='consoleserverport', - name='cable', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'), - ), - migrations.AddField( - model_name='consoleserverport', - name='device', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'), - ), - migrations.AddField( - model_name='consoleserverport', - name='module', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.module'), - ), - migrations.AddField( - model_name='consoleserverport', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='consoleporttemplate', - name='device_type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), - ), - migrations.AddField( - model_name='consoleporttemplate', - name='module_type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'), - ), - migrations.AddField( - model_name='consoleport', - name='_path', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'), - ), - migrations.AddField( - model_name='consoleport', - name='cable', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'), - ), - migrations.AddField( - model_name='consoleport', - name='device', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'), - ), - migrations.AddField( - model_name='consoleport', - name='module', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.module'), - ), - migrations.AddField( - model_name='consoleport', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='cabletermination', - name='_device', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dcim.device'), - ), - migrations.AddField( - model_name='cabletermination', - name='_location', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dcim.location'), - ), - migrations.AddField( - model_name='cabletermination', - name='_rack', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dcim.rack'), - ), - migrations.AddField( - model_name='cabletermination', - name='_site', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dcim.site'), - ), - migrations.AddField( - model_name='cabletermination', - name='cable', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='terminations', to='dcim.cable'), - ), - migrations.AddField( - model_name='cabletermination', - name='termination_type', - field=models.ForeignKey(limit_choices_to=models.Q(models.Q(models.Q(('app_label', 'circuits'), ('model__in', ('circuittermination',))), models.Q(('app_label', 'dcim'), ('model__in', ('consoleport', 'consoleserverport', 'frontport', 'interface', 'powerfeed', 'poweroutlet', 'powerport', 'rearport'))), _connector='OR')), on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype'), - ), - migrations.AddField( - model_name='cable', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='cable', - name='tenant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='cables', to='tenancy.tenant'), - ), - migrations.AddConstraint( - model_name='virtualdevicecontext', - constraint=models.UniqueConstraint(fields=('device', 'identifier'), name='dcim_virtualdevicecontext_device_identifier'), - ), - migrations.AddConstraint( - model_name='virtualdevicecontext', - constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_virtualdevicecontext_device_name'), - ), - migrations.AddConstraint( - model_name='sitegroup', - constraint=models.UniqueConstraint(fields=('parent', 'name'), name='dcim_sitegroup_parent_name'), - ), - migrations.AddConstraint( - model_name='sitegroup', - constraint=models.UniqueConstraint(condition=models.Q(('parent__isnull', True)), fields=('name',), name='dcim_sitegroup_name', violation_error_message='A top-level site group with this name already exists.'), - ), - migrations.AddConstraint( - model_name='sitegroup', - constraint=models.UniqueConstraint(fields=('parent', 'slug'), name='dcim_sitegroup_parent_slug'), - ), - migrations.AddConstraint( - model_name='sitegroup', - constraint=models.UniqueConstraint(condition=models.Q(('parent__isnull', True)), fields=('slug',), name='dcim_sitegroup_slug', violation_error_message='A top-level site group with this slug already exists.'), - ), - migrations.AddConstraint( - model_name='region', - constraint=models.UniqueConstraint(fields=('parent', 'name'), name='dcim_region_parent_name'), - ), - migrations.AddConstraint( - model_name='region', - constraint=models.UniqueConstraint(condition=models.Q(('parent__isnull', True)), fields=('name',), name='dcim_region_name', violation_error_message='A top-level region with this name already exists.'), - ), - migrations.AddConstraint( - model_name='region', - constraint=models.UniqueConstraint(fields=('parent', 'slug'), name='dcim_region_parent_slug'), - ), - migrations.AddConstraint( - model_name='region', - constraint=models.UniqueConstraint(condition=models.Q(('parent__isnull', True)), fields=('slug',), name='dcim_region_slug', violation_error_message='A top-level region with this slug already exists.'), - ), - migrations.AddConstraint( - model_name='rearporttemplate', - constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_rearporttemplate_unique_device_type_name'), - ), - migrations.AddConstraint( - model_name='rearporttemplate', - constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_rearporttemplate_unique_module_type_name'), - ), - migrations.AddConstraint( - model_name='rearport', - constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_rearport_unique_device_name'), - ), - migrations.AddConstraint( - model_name='rack', - constraint=models.UniqueConstraint(fields=('location', 'name'), name='dcim_rack_unique_location_name'), - ), - migrations.AddConstraint( - model_name='rack', - constraint=models.UniqueConstraint(fields=('location', 'facility_id'), name='dcim_rack_unique_location_facility_id'), - ), - migrations.AddConstraint( - model_name='powerporttemplate', - constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_powerporttemplate_unique_device_type_name'), - ), - migrations.AddConstraint( - model_name='powerporttemplate', - constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_powerporttemplate_unique_module_type_name'), - ), - migrations.AddConstraint( - model_name='powerport', - constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_powerport_unique_device_name'), - ), - migrations.AddConstraint( - model_name='powerpanel', - constraint=models.UniqueConstraint(fields=('site', 'name'), name='dcim_powerpanel_unique_site_name'), - ), - migrations.AddConstraint( - model_name='poweroutlettemplate', - constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_poweroutlettemplate_unique_device_type_name'), - ), - migrations.AddConstraint( - model_name='poweroutlettemplate', - constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_poweroutlettemplate_unique_module_type_name'), - ), - migrations.AddConstraint( - model_name='poweroutlet', - constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_poweroutlet_unique_device_name'), - ), - migrations.AddConstraint( - model_name='powerfeed', - constraint=models.UniqueConstraint(fields=('power_panel', 'name'), name='dcim_powerfeed_unique_power_panel_name'), - ), - migrations.AddConstraint( - model_name='moduletype', - constraint=models.UniqueConstraint(fields=('manufacturer', 'model'), name='dcim_moduletype_unique_manufacturer_model'), - ), - migrations.AddConstraint( - model_name='modulebaytemplate', - constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_modulebaytemplate_unique_device_type_name'), - ), - migrations.AddConstraint( - model_name='modulebay', - constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_modulebay_unique_device_name'), - ), - migrations.AddConstraint( - model_name='location', - constraint=models.UniqueConstraint(fields=('site', 'parent', 'name'), name='dcim_location_parent_name'), - ), - migrations.AddConstraint( - model_name='location', - constraint=models.UniqueConstraint(condition=models.Q(('parent__isnull', True)), fields=('site', 'name'), name='dcim_location_name', violation_error_message='A location with this name already exists within the specified site.'), - ), - migrations.AddConstraint( - model_name='location', - constraint=models.UniqueConstraint(fields=('site', 'parent', 'slug'), name='dcim_location_parent_slug'), - ), - migrations.AddConstraint( - model_name='location', - constraint=models.UniqueConstraint(condition=models.Q(('parent__isnull', True)), fields=('site', 'slug'), name='dcim_location_slug', violation_error_message='A location with this slug already exists within the specified site.'), - ), - migrations.AddConstraint( - model_name='inventoryitemtemplate', - constraint=models.UniqueConstraint(fields=('device_type', 'parent', 'name'), name='dcim_inventoryitemtemplate_unique_device_type_parent_name'), - ), - migrations.AddConstraint( - model_name='inventoryitem', - constraint=models.UniqueConstraint(fields=('device', 'parent', 'name'), name='dcim_inventoryitem_unique_device_parent_name'), - ), - migrations.AddConstraint( - model_name='interfacetemplate', - constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_interfacetemplate_unique_device_type_name'), - ), - migrations.AddConstraint( - model_name='interfacetemplate', - constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_interfacetemplate_unique_module_type_name'), - ), - migrations.AddConstraint( - model_name='interface', - constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_interface_unique_device_name'), - ), - migrations.AddConstraint( - model_name='frontporttemplate', - constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_frontporttemplate_unique_device_type_name'), - ), - migrations.AddConstraint( - model_name='frontporttemplate', - constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_frontporttemplate_unique_module_type_name'), - ), - migrations.AddConstraint( - model_name='frontporttemplate', - constraint=models.UniqueConstraint(fields=('rear_port', 'rear_port_position'), name='dcim_frontporttemplate_unique_rear_port_position'), - ), - migrations.AddConstraint( - model_name='frontport', - constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_frontport_unique_device_name'), - ), - migrations.AddConstraint( - model_name='frontport', - constraint=models.UniqueConstraint(fields=('rear_port', 'rear_port_position'), name='dcim_frontport_unique_rear_port_position'), - ), - migrations.AddConstraint( - model_name='devicetype', - constraint=models.UniqueConstraint(fields=('manufacturer', 'model'), name='dcim_devicetype_unique_manufacturer_model'), - ), - migrations.AddConstraint( - model_name='devicetype', - constraint=models.UniqueConstraint(fields=('manufacturer', 'slug'), name='dcim_devicetype_unique_manufacturer_slug'), - ), - migrations.AddConstraint( - model_name='devicebaytemplate', - constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_devicebaytemplate_unique_device_type_name'), - ), - migrations.AddConstraint( - model_name='devicebay', - constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_devicebay_unique_device_name'), - ), - migrations.AddConstraint( - model_name='device', - constraint=models.UniqueConstraint(django.db.models.functions.text.Lower('name'), models.F('site'), models.F('tenant'), name='dcim_device_unique_name_site_tenant'), - ), - migrations.AddConstraint( - model_name='device', - constraint=models.UniqueConstraint(django.db.models.functions.text.Lower('name'), models.F('site'), condition=models.Q(('tenant__isnull', True)), name='dcim_device_unique_name_site', violation_error_message='Device name must be unique per site.'), - ), - migrations.AddConstraint( - model_name='device', - constraint=models.UniqueConstraint(fields=('rack', 'position', 'face'), name='dcim_device_unique_rack_position_face'), - ), - migrations.AddConstraint( - model_name='device', - constraint=models.UniqueConstraint(fields=('virtual_chassis', 'vc_position'), name='dcim_device_unique_virtual_chassis_vc_position'), - ), - migrations.AddConstraint( - model_name='consoleserverporttemplate', - constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_consoleserverporttemplate_unique_device_type_name'), - ), - migrations.AddConstraint( - model_name='consoleserverporttemplate', - constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_consoleserverporttemplate_unique_module_type_name'), - ), - migrations.AddConstraint( - model_name='consoleserverport', - constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_consoleserverport_unique_device_name'), - ), - migrations.AddConstraint( - model_name='consoleporttemplate', - constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_consoleporttemplate_unique_device_type_name'), - ), - migrations.AddConstraint( - model_name='consoleporttemplate', - constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_consoleporttemplate_unique_module_type_name'), - ), - migrations.AddConstraint( - model_name='consoleport', - constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_consoleport_unique_device_name'), - ), - migrations.AddConstraint( - model_name='cabletermination', - constraint=models.UniqueConstraint(fields=('termination_type', 'termination_id'), name='dcim_cabletermination_unique_termination'), - ), - ] diff --git a/netbox/dcim/migrations/0003_squashed_0130.py b/netbox/dcim/migrations/0003_squashed_0130.py new file mode 100644 index 000000000..592aaf9a8 --- /dev/null +++ b/netbox/dcim/migrations/0003_squashed_0130.py @@ -0,0 +1,485 @@ +from django.db import migrations, models +import django.db.models.deletion +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0002_auto_20160622_1821'), + ('virtualization', '0001_virtualization'), + ('contenttypes', '0002_remove_content_type_name'), + ('ipam', '0001_initial'), + ('tenancy', '0001_initial'), + ('extras', '0002_custom_fields'), + ] + + replaces = [ + ('dcim', '0003_auto_20160628_1721'), + ('dcim', '0004_auto_20160701_2049'), + ('dcim', '0005_auto_20160706_1722'), + ('dcim', '0006_add_device_primary_ip4_ip6'), + ('dcim', '0007_device_copy_primary_ip'), + ('dcim', '0008_device_remove_primary_ip'), + ('dcim', '0009_site_32bit_asn_support'), + ('dcim', '0010_devicebay_installed_device_set_null'), + ('dcim', '0011_devicetype_part_number'), + ('dcim', '0012_site_rack_device_add_tenant'), + ('dcim', '0013_add_interface_form_factors'), + ('dcim', '0014_rack_add_type_width'), + ('dcim', '0015_rack_add_u_height_validator'), + ('dcim', '0016_module_add_manufacturer'), + ('dcim', '0017_rack_add_role'), + ('dcim', '0018_device_add_asset_tag'), + ('dcim', '0019_new_iface_form_factors'), + ('dcim', '0020_rack_desc_units'), + ('dcim', '0021_add_ff_flexstack'), + ('dcim', '0022_color_names_to_rgb'), + ('dcim', '0023_devicetype_comments'), + ('dcim', '0024_site_add_contact_fields'), + ('dcim', '0025_devicetype_add_interface_ordering'), + ('dcim', '0026_add_rack_reservations'), + ('dcim', '0027_device_add_site'), + ('dcim', '0028_device_copy_rack_to_site'), + ('dcim', '0029_allow_rackless_devices'), + ('dcim', '0030_interface_add_lag'), + ('dcim', '0031_regions'), + ('dcim', '0032_device_increase_name_length'), + ('dcim', '0033_rackreservation_rack_editable'), + ('dcim', '0034_rename_module_to_inventoryitem'), + ('dcim', '0035_device_expand_status_choices'), + ('dcim', '0036_add_ff_juniper_vcp'), + ('dcim', '0037_unicode_literals'), + ('dcim', '0038_wireless_interfaces'), + ('dcim', '0039_interface_add_enabled_mtu'), + ('dcim', '0040_inventoryitem_add_asset_tag_description'), + ('dcim', '0041_napalm_integration'), + ('dcim', '0042_interface_ff_10ge_cx4'), + ('dcim', '0043_device_component_name_lengths'), + ('dcim', '0044_virtualization'), + ('dcim', '0045_devicerole_vm_role'), + ('dcim', '0046_rack_lengthen_facility_id'), + ('dcim', '0047_more_100ge_form_factors'), + ('dcim', '0048_rack_serial'), + ('dcim', '0049_rackreservation_change_user'), + ('dcim', '0050_interface_vlan_tagging'), + ('dcim', '0051_rackreservation_tenant'), + ('dcim', '0052_virtual_chassis'), + ('dcim', '0053_platform_manufacturer'), + ('dcim', '0054_site_status_timezone_description'), + ('dcim', '0055_virtualchassis_ordering'), + ('dcim', '0056_django2'), + ('dcim', '0057_tags'), + ('dcim', '0058_relax_rack_naming_constraints'), + ('dcim', '0059_site_latitude_longitude'), + ('dcim', '0060_change_logging'), + ('dcim', '0061_platform_napalm_args'), + ('dcim', '0062_interface_mtu'), + ('dcim', '0063_device_local_context_data'), + ('dcim', '0064_remove_platform_rpc_client'), + ('dcim', '0065_front_rear_ports'), + ('dcim', '0066_cables'), + ('dcim', '0067_device_type_remove_qualifiers'), + ('dcim', '0068_rack_new_fields'), + ('dcim', '0069_deprecate_nullablecharfield'), + ('dcim', '0070_custom_tag_models'), + ('dcim', '0071_device_components_add_description'), + ('dcim', '0072_powerfeeds'), + ('dcim', '0073_interface_form_factor_to_type'), + ('dcim', '0074_increase_field_length_platform_name_slug'), + ('dcim', '0075_cable_devices'), + ('dcim', '0076_console_port_types'), + ('dcim', '0077_power_types'), + ('dcim', '0078_3569_site_fields'), + ('dcim', '0079_3569_rack_fields'), + ('dcim', '0080_3569_devicetype_fields'), + ('dcim', '0081_3569_device_fields'), + ('dcim', '0082_3569_interface_fields'), + ('dcim', '0082_3569_port_fields'), + ('dcim', '0083_3569_cable_fields'), + ('dcim', '0084_3569_powerfeed_fields'), + ('dcim', '0085_3569_poweroutlet_fields'), + ('dcim', '0086_device_name_nonunique'), + ('dcim', '0087_role_descriptions'), + ('dcim', '0088_powerfeed_available_power'), + ('dcim', '0089_deterministic_ordering'), + ('dcim', '0090_cable_termination_models'), + ('dcim', '0091_interface_type_other'), + ('dcim', '0092_fix_rack_outer_unit'), + ('dcim', '0093_device_component_ordering'), + ('dcim', '0094_device_component_template_ordering'), + ('dcim', '0095_primary_model_ordering'), + ('dcim', '0096_interface_ordering'), + ('dcim', '0097_interfacetemplate_type_other'), + ('dcim', '0098_devicetype_images'), + ('dcim', '0099_powerfeed_negative_voltage'), + ('dcim', '0100_mptt_remove_indexes'), + ('dcim', '0101_nested_rackgroups'), + ('dcim', '0102_nested_rackgroups_rebuild'), + ('dcim', '0103_standardize_description'), + ('dcim', '0104_correct_infiniband_types'), + ('dcim', '0105_interface_name_collation'), + ('dcim', '0106_role_default_color'), + ('dcim', '0107_component_labels'), + ('dcim', '0108_add_tags'), + ('dcim', '0109_interface_remove_vm'), + ('dcim', '0110_virtualchassis_name'), + ('dcim', '0111_component_template_description'), + ('dcim', '0112_standardize_components'), + ('dcim', '0113_nullbooleanfield_to_booleanfield'), + ('dcim', '0114_update_jsonfield'), + ('dcim', '0115_rackreservation_order'), + ('dcim', '0116_rearport_max_positions'), + ('dcim', '0117_custom_field_data'), + ('dcim', '0118_inventoryitem_mptt'), + ('dcim', '0119_inventoryitem_mptt_rebuild'), + ('dcim', '0120_cache_cable_peer'), + ('dcim', '0121_cablepath'), + ('dcim', '0122_standardize_name_length'), + ('dcim', '0123_standardize_models'), + ('dcim', '0124_mark_connected'), + ('dcim', '0125_console_port_speed'), + ('dcim', '0126_rename_rackgroup_location'), + ('dcim', '0127_device_location'), + ('dcim', '0128_device_location_populate'), + ('dcim', '0129_interface_parent'), + ('dcim', '0130_sitegroup'), + ] + + operations = [ + migrations.AddField( + model_name='interface', + name='tagged_vlans', + field=models.ManyToManyField(blank=True, related_name='interfaces_as_tagged', to='ipam.VLAN'), + ), + migrations.AddField( + model_name='interface', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='interface', + name='untagged_vlan', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='interfaces_as_untagged', to='ipam.vlan'), + ), + migrations.AddField( + model_name='frontporttemplate', + name='device_type', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), + ), + migrations.AddField( + model_name='frontporttemplate', + name='rear_port', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='frontport_templates', to='dcim.rearporttemplate'), + ), + migrations.AddField( + model_name='frontport', + name='_cable_peer_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'), + ), + migrations.AddField( + model_name='frontport', + name='cable', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'), + ), + migrations.AddField( + model_name='frontport', + name='device', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'), + ), + migrations.AddField( + model_name='frontport', + name='rear_port', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='frontports', to='dcim.rearport'), + ), + migrations.AddField( + model_name='frontport', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='devicetype', + name='manufacturer', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='device_types', to='dcim.manufacturer'), + ), + migrations.AddField( + model_name='devicetype', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='devicebaytemplate', + name='device_type', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), + ), + migrations.AddField( + model_name='devicebay', + name='device', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'), + ), + migrations.AddField( + model_name='devicebay', + name='installed_device', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='parent_bay', to='dcim.device'), + ), + migrations.AddField( + model_name='devicebay', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='device', + name='cluster', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='devices', to='virtualization.cluster'), + ), + migrations.AddField( + model_name='device', + name='device_role', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='dcim.devicerole'), + ), + migrations.AddField( + model_name='device', + name='device_type', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='instances', to='dcim.devicetype'), + ), + migrations.AddField( + model_name='device', + name='location', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='dcim.location'), + ), + migrations.AddField( + model_name='device', + name='platform', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='devices', to='dcim.platform'), + ), + migrations.AddField( + model_name='device', + name='primary_ip4', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='primary_ip4_for', to='ipam.ipaddress'), + ), + migrations.AddField( + model_name='device', + name='primary_ip6', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='primary_ip6_for', to='ipam.ipaddress'), + ), + migrations.AddField( + model_name='device', + name='rack', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='dcim.rack'), + ), + migrations.AddField( + model_name='device', + name='site', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='dcim.site'), + ), + migrations.AddField( + model_name='device', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='device', + name='tenant', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='tenancy.tenant'), + ), + migrations.AddField( + model_name='device', + name='virtual_chassis', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='members', to='dcim.virtualchassis'), + ), + migrations.AddField( + model_name='consoleserverporttemplate', + name='device_type', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), + ), + migrations.AddField( + model_name='consoleserverport', + name='_cable_peer_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'), + ), + migrations.AddField( + model_name='consoleserverport', + name='_path', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'), + ), + migrations.AddField( + model_name='consoleserverport', + name='cable', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'), + ), + migrations.AddField( + model_name='consoleserverport', + name='device', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'), + ), + migrations.AddField( + model_name='consoleserverport', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='consoleporttemplate', + name='device_type', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), + ), + migrations.AddField( + model_name='consoleport', + name='_cable_peer_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'), + ), + migrations.AddField( + model_name='consoleport', + name='_path', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'), + ), + migrations.AddField( + model_name='consoleport', + name='cable', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'), + ), + migrations.AddField( + model_name='consoleport', + name='device', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'), + ), + migrations.AddField( + model_name='consoleport', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='cablepath', + name='destination_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='contenttypes.contenttype'), + ), + migrations.AddField( + model_name='cablepath', + name='origin_type', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='contenttypes.contenttype'), + ), + migrations.AddField( + model_name='cable', + name='_termination_a_device', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='dcim.device'), + ), + migrations.AddField( + model_name='cable', + name='_termination_b_device', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='dcim.device'), + ), + migrations.AddField( + model_name='cable', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='cable', + name='termination_a_type', + field=models.ForeignKey(limit_choices_to=models.Q(models.Q(models.Q(('app_label', 'circuits'), ('model__in', ('circuittermination',))), models.Q(('app_label', 'dcim'), ('model__in', ('consoleport', 'consoleserverport', 'frontport', 'interface', 'powerfeed', 'poweroutlet', 'powerport', 'rearport'))), _connector='OR')), on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype'), + ), + migrations.AddField( + model_name='cable', + name='termination_b_type', + field=models.ForeignKey(limit_choices_to=models.Q(models.Q(models.Q(('app_label', 'circuits'), ('model__in', ('circuittermination',))), models.Q(('app_label', 'dcim'), ('model__in', ('consoleport', 'consoleserverport', 'frontport', 'interface', 'powerfeed', 'poweroutlet', 'powerport', 'rearport'))), _connector='OR')), on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype'), + ), + migrations.AlterUniqueTogether( + name='rearporttemplate', + unique_together={('device_type', 'name')}, + ), + migrations.AlterUniqueTogether( + name='rearport', + unique_together={('device', 'name')}, + ), + migrations.AlterUniqueTogether( + name='rack', + unique_together={('location', 'facility_id'), ('location', 'name')}, + ), + migrations.AlterUniqueTogether( + name='powerporttemplate', + unique_together={('device_type', 'name')}, + ), + migrations.AlterUniqueTogether( + name='powerport', + unique_together={('device', 'name')}, + ), + migrations.AlterUniqueTogether( + name='powerpanel', + unique_together={('site', 'name')}, + ), + migrations.AlterUniqueTogether( + name='poweroutlettemplate', + unique_together={('device_type', 'name')}, + ), + migrations.AlterUniqueTogether( + name='poweroutlet', + unique_together={('device', 'name')}, + ), + migrations.AlterUniqueTogether( + name='powerfeed', + unique_together={('power_panel', 'name')}, + ), + migrations.AlterUniqueTogether( + name='location', + unique_together={('site', 'name'), ('site', 'slug')}, + ), + migrations.AlterUniqueTogether( + name='inventoryitem', + unique_together={('device', 'parent', 'name')}, + ), + migrations.AlterUniqueTogether( + name='interfacetemplate', + unique_together={('device_type', 'name')}, + ), + migrations.AlterUniqueTogether( + name='interface', + unique_together={('device', 'name')}, + ), + migrations.AlterUniqueTogether( + name='frontporttemplate', + unique_together={('rear_port', 'rear_port_position'), ('device_type', 'name')}, + ), + migrations.AlterUniqueTogether( + name='frontport', + unique_together={('device', 'name'), ('rear_port', 'rear_port_position')}, + ), + migrations.AlterUniqueTogether( + name='devicetype', + unique_together={('manufacturer', 'model'), ('manufacturer', 'slug')}, + ), + migrations.AlterUniqueTogether( + name='devicebaytemplate', + unique_together={('device_type', 'name')}, + ), + migrations.AlterUniqueTogether( + name='devicebay', + unique_together={('device', 'name')}, + ), + migrations.AlterUniqueTogether( + name='device', + unique_together={('rack', 'position', 'face'), ('virtual_chassis', 'vc_position'), ('site', 'tenant', 'name')}, + ), + migrations.AlterUniqueTogether( + name='consoleserverporttemplate', + unique_together={('device_type', 'name')}, + ), + migrations.AlterUniqueTogether( + name='consoleserverport', + unique_together={('device', 'name')}, + ), + migrations.AlterUniqueTogether( + name='consoleporttemplate', + unique_together={('device_type', 'name')}, + ), + migrations.AlterUniqueTogether( + name='consoleport', + unique_together={('device', 'name')}, + ), + migrations.AlterUniqueTogether( + name='cablepath', + unique_together={('origin_type', 'origin_id')}, + ), + migrations.AlterUniqueTogether( + name='cable', + unique_together={('termination_b_type', 'termination_b_id'), ('termination_a_type', 'termination_a_id')}, + ), + ] diff --git a/netbox/dcim/migrations/0131_consoleport_speed.py b/netbox/dcim/migrations/0131_consoleport_speed.py new file mode 100644 index 000000000..350162218 --- /dev/null +++ b/netbox/dcim/migrations/0131_consoleport_speed.py @@ -0,0 +1,21 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0130_sitegroup'), + ] + + operations = [ + migrations.AlterField( + model_name='consoleport', + name='speed', + field=models.PositiveIntegerField(blank=True, null=True), + ), + migrations.AlterField( + model_name='consoleserverport', + name='speed', + field=models.PositiveIntegerField(blank=True, null=True), + ), + ] diff --git a/netbox/dcim/migrations/0132_cable_length.py b/netbox/dcim/migrations/0132_cable_length.py new file mode 100644 index 000000000..e20a8b8aa --- /dev/null +++ b/netbox/dcim/migrations/0132_cable_length.py @@ -0,0 +1,16 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0131_consoleport_speed'), + ] + + operations = [ + migrations.AlterField( + model_name='cable', + name='length', + field=models.DecimalField(blank=True, decimal_places=2, max_digits=8, null=True), + ), + ] diff --git a/netbox/dcim/migrations/0133_port_colors.py b/netbox/dcim/migrations/0133_port_colors.py new file mode 100644 index 000000000..8cae7ac8e --- /dev/null +++ b/netbox/dcim/migrations/0133_port_colors.py @@ -0,0 +1,32 @@ +from django.db import migrations +import utilities.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0132_cable_length'), + ] + + operations = [ + migrations.AddField( + model_name='frontport', + name='color', + field=utilities.fields.ColorField(blank=True, max_length=6), + ), + migrations.AddField( + model_name='frontporttemplate', + name='color', + field=utilities.fields.ColorField(blank=True, max_length=6), + ), + migrations.AddField( + model_name='rearport', + name='color', + field=utilities.fields.ColorField(blank=True, max_length=6), + ), + migrations.AddField( + model_name='rearporttemplate', + name='color', + field=utilities.fields.ColorField(blank=True, max_length=6), + ), + ] diff --git a/netbox/dcim/migrations/0134_interface_wwn_bridge.py b/netbox/dcim/migrations/0134_interface_wwn_bridge.py new file mode 100644 index 000000000..a900ae6be --- /dev/null +++ b/netbox/dcim/migrations/0134_interface_wwn_bridge.py @@ -0,0 +1,23 @@ +import dcim.fields +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0133_port_colors'), + ] + + operations = [ + migrations.AddField( + model_name='interface', + name='wwn', + field=dcim.fields.WWNField(blank=True, null=True), + ), + migrations.AddField( + model_name='interface', + name='bridge', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='bridge_interfaces', to='dcim.interface'), + ), + ] diff --git a/netbox/dcim/migrations/0135_tenancy_extensions.py b/netbox/dcim/migrations/0135_tenancy_extensions.py new file mode 100644 index 000000000..96d765eea --- /dev/null +++ b/netbox/dcim/migrations/0135_tenancy_extensions.py @@ -0,0 +1,23 @@ +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('tenancy', '0002_tenant_ordering'), + ('dcim', '0134_interface_wwn_bridge'), + ] + + operations = [ + migrations.AddField( + model_name='location', + name='tenant', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='locations', to='tenancy.tenant'), + ), + migrations.AddField( + model_name='cable', + name='tenant', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='cables', to='tenancy.tenant'), + ), + ] diff --git a/netbox/dcim/migrations/0136_device_airflow.py b/netbox/dcim/migrations/0136_device_airflow.py new file mode 100644 index 000000000..94cc89f3f --- /dev/null +++ b/netbox/dcim/migrations/0136_device_airflow.py @@ -0,0 +1,21 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0135_tenancy_extensions'), + ] + + operations = [ + migrations.AddField( + model_name='devicetype', + name='airflow', + field=models.CharField(blank=True, max_length=50), + ), + migrations.AddField( + model_name='device', + name='airflow', + field=models.CharField(blank=True, max_length=50), + ), + ] diff --git a/netbox/dcim/migrations/0137_relax_uniqueness_constraints.py b/netbox/dcim/migrations/0137_relax_uniqueness_constraints.py new file mode 100644 index 000000000..7cedb1b08 --- /dev/null +++ b/netbox/dcim/migrations/0137_relax_uniqueness_constraints.py @@ -0,0 +1,83 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0136_device_airflow'), + ] + + operations = [ + migrations.AlterField( + model_name='region', + name='name', + field=models.CharField(max_length=100), + ), + migrations.AlterField( + model_name='region', + name='slug', + field=models.SlugField(max_length=100), + ), + migrations.AlterField( + model_name='sitegroup', + name='name', + field=models.CharField(max_length=100), + ), + migrations.AlterField( + model_name='sitegroup', + name='slug', + field=models.SlugField(max_length=100), + ), + migrations.AlterUniqueTogether( + name='location', + unique_together=set(), + ), + migrations.AddConstraint( + model_name='location', + constraint=models.UniqueConstraint(fields=('site', 'parent', 'name'), name='dcim_location_parent_name'), + ), + migrations.AddConstraint( + model_name='location', + constraint=models.UniqueConstraint(condition=models.Q(('parent', None)), fields=('site', 'name'), name='dcim_location_name'), + ), + migrations.AddConstraint( + model_name='location', + constraint=models.UniqueConstraint(fields=('site', 'parent', 'slug'), name='dcim_location_parent_slug'), + ), + migrations.AddConstraint( + model_name='location', + constraint=models.UniqueConstraint(condition=models.Q(('parent', None)), fields=('site', 'slug'), name='dcim_location_slug'), + ), + migrations.AddConstraint( + model_name='region', + constraint=models.UniqueConstraint(fields=('parent', 'name'), name='dcim_region_parent_name'), + ), + migrations.AddConstraint( + model_name='region', + constraint=models.UniqueConstraint(condition=models.Q(('parent', None)), fields=('name',), name='dcim_region_name'), + ), + migrations.AddConstraint( + model_name='region', + constraint=models.UniqueConstraint(fields=('parent', 'slug'), name='dcim_region_parent_slug'), + ), + migrations.AddConstraint( + model_name='region', + constraint=models.UniqueConstraint(condition=models.Q(('parent', None)), fields=('slug',), name='dcim_region_slug'), + ), + migrations.AddConstraint( + model_name='sitegroup', + constraint=models.UniqueConstraint(fields=('parent', 'name'), name='dcim_sitegroup_parent_name'), + ), + migrations.AddConstraint( + model_name='sitegroup', + constraint=models.UniqueConstraint(condition=models.Q(('parent', None)), fields=('name',), name='dcim_sitegroup_name'), + ), + migrations.AddConstraint( + model_name='sitegroup', + constraint=models.UniqueConstraint(fields=('parent', 'slug'), name='dcim_sitegroup_parent_slug'), + ), + migrations.AddConstraint( + model_name='sitegroup', + constraint=models.UniqueConstraint(condition=models.Q(('parent', None)), fields=('slug',), name='dcim_sitegroup_slug'), + ), + ] diff --git a/netbox/dcim/migrations/0138_extend_tag_support.py b/netbox/dcim/migrations/0138_extend_tag_support.py new file mode 100644 index 000000000..763b53c50 --- /dev/null +++ b/netbox/dcim/migrations/0138_extend_tag_support.py @@ -0,0 +1,50 @@ +# Generated by Django 3.2.8 on 2021-10-21 14:50 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0062_clear_secrets_changelog'), + ('dcim', '0137_relax_uniqueness_constraints'), + ] + + operations = [ + migrations.AddField( + model_name='devicerole', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='location', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='manufacturer', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='platform', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='rackrole', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='region', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='sitegroup', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + ] diff --git a/netbox/dcim/migrations/0139_rename_cable_peer.py b/netbox/dcim/migrations/0139_rename_cable_peer.py new file mode 100644 index 000000000..59dc04e2a --- /dev/null +++ b/netbox/dcim/migrations/0139_rename_cable_peer.py @@ -0,0 +1,91 @@ +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0138_extend_tag_support'), + ] + + operations = [ + migrations.RenameField( + model_name='consoleport', + old_name='_cable_peer_id', + new_name='_link_peer_id', + ), + migrations.RenameField( + model_name='consoleport', + old_name='_cable_peer_type', + new_name='_link_peer_type', + ), + migrations.RenameField( + model_name='consoleserverport', + old_name='_cable_peer_id', + new_name='_link_peer_id', + ), + migrations.RenameField( + model_name='consoleserverport', + old_name='_cable_peer_type', + new_name='_link_peer_type', + ), + migrations.RenameField( + model_name='frontport', + old_name='_cable_peer_id', + new_name='_link_peer_id', + ), + migrations.RenameField( + model_name='frontport', + old_name='_cable_peer_type', + new_name='_link_peer_type', + ), + migrations.RenameField( + model_name='interface', + old_name='_cable_peer_id', + new_name='_link_peer_id', + ), + migrations.RenameField( + model_name='interface', + old_name='_cable_peer_type', + new_name='_link_peer_type', + ), + migrations.RenameField( + model_name='powerfeed', + old_name='_cable_peer_id', + new_name='_link_peer_id', + ), + migrations.RenameField( + model_name='powerfeed', + old_name='_cable_peer_type', + new_name='_link_peer_type', + ), + migrations.RenameField( + model_name='poweroutlet', + old_name='_cable_peer_id', + new_name='_link_peer_id', + ), + migrations.RenameField( + model_name='poweroutlet', + old_name='_cable_peer_type', + new_name='_link_peer_type', + ), + migrations.RenameField( + model_name='powerport', + old_name='_cable_peer_id', + new_name='_link_peer_id', + ), + migrations.RenameField( + model_name='powerport', + old_name='_cable_peer_type', + new_name='_link_peer_type', + ), + migrations.RenameField( + model_name='rearport', + old_name='_cable_peer_id', + new_name='_link_peer_id', + ), + migrations.RenameField( + model_name='rearport', + old_name='_cable_peer_type', + new_name='_link_peer_type', + ), + ] diff --git a/netbox/dcim/migrations/0140_wireless.py b/netbox/dcim/migrations/0140_wireless.py new file mode 100644 index 000000000..430782cf0 --- /dev/null +++ b/netbox/dcim/migrations/0140_wireless.py @@ -0,0 +1,49 @@ +from django.db import migrations, models +import django.core.validators +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0139_rename_cable_peer'), + ('wireless', '0001_wireless'), + ] + + operations = [ + migrations.AddField( + model_name='interface', + name='rf_role', + field=models.CharField(blank=True, max_length=30), + ), + migrations.AddField( + model_name='interface', + name='rf_channel', + field=models.CharField(blank=True, max_length=50), + ), + migrations.AddField( + model_name='interface', + name='rf_channel_frequency', + field=models.DecimalField(blank=True, decimal_places=2, max_digits=7, null=True), + ), + migrations.AddField( + model_name='interface', + name='rf_channel_width', + field=models.DecimalField(blank=True, decimal_places=3, max_digits=7, null=True), + ), + migrations.AddField( + model_name='interface', + name='tx_power', + field=models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(127)]), + ), + migrations.AddField( + model_name='interface', + name='wireless_lans', + field=models.ManyToManyField(blank=True, related_name='interfaces', to='wireless.WirelessLAN'), + ), + migrations.AddField( + model_name='interface', + name='wireless_link', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wireless.wirelesslink'), + ), + ] diff --git a/netbox/dcim/migrations/0141_asn_model.py b/netbox/dcim/migrations/0141_asn_model.py new file mode 100644 index 000000000..6f011f35d --- /dev/null +++ b/netbox/dcim/migrations/0141_asn_model.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2.8 on 2021-11-02 16:16 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0053_asn_model'), + ('dcim', '0140_wireless'), + ] + + operations = [ + migrations.AddField( + model_name='site', + name='asns', + field=models.ManyToManyField(blank=True, related_name='sites', to='ipam.ASN'), + ), + ] diff --git a/netbox/dcim/migrations/0142_rename_128gfc_qsfp28.py b/netbox/dcim/migrations/0142_rename_128gfc_qsfp28.py new file mode 100644 index 000000000..d1f91afae --- /dev/null +++ b/netbox/dcim/migrations/0142_rename_128gfc_qsfp28.py @@ -0,0 +1,29 @@ +from django.db import migrations + +OLD_VALUE = '128gfc-sfp28' +NEW_VALUE = '128gfc-qsfp28' + + +def correct_type(apps, schema_editor): + """ + Correct TYPE_128GFC_QSFP28 interface type. + """ + Interface = apps.get_model('dcim', 'Interface') + InterfaceTemplate = apps.get_model('dcim', 'InterfaceTemplate') + + for model in (Interface, InterfaceTemplate): + model.objects.filter(type=OLD_VALUE).update(type=NEW_VALUE) + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0141_asn_model'), + ] + + operations = [ + migrations.RunPython( + code=correct_type, + reverse_code=migrations.RunPython.noop + ), + ] diff --git a/netbox/dcim/migrations/0143_remove_primary_for_related_name.py b/netbox/dcim/migrations/0143_remove_primary_for_related_name.py new file mode 100644 index 000000000..820c9e3fe --- /dev/null +++ b/netbox/dcim/migrations/0143_remove_primary_for_related_name.py @@ -0,0 +1,23 @@ +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0053_asn_model'), + ('dcim', '0142_rename_128gfc_qsfp28'), + ] + + operations = [ + migrations.AlterField( + model_name='device', + name='primary_ip4', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='ipam.ipaddress'), + ), + migrations.AlterField( + model_name='device', + name='primary_ip6', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='ipam.ipaddress'), + ), + ] diff --git a/netbox/dcim/migrations/0144_fix_cable_abs_length.py b/netbox/dcim/migrations/0144_fix_cable_abs_length.py new file mode 100644 index 000000000..0da30ffb5 --- /dev/null +++ b/netbox/dcim/migrations/0144_fix_cable_abs_length.py @@ -0,0 +1,31 @@ +from django.db import migrations + +from utilities.utils import to_meters + + +def recalculate_abs_length(apps, schema_editor): + """ + Recalculate absolute lengths for all cables with a length and length unit defined. Fixes + incorrectly calculated values as reported under bug #8377. + """ + Cable = apps.get_model('dcim', 'Cable') + + cables = Cable.objects.filter(length__isnull=False).exclude(length_unit='') + for cable in cables: + cable._abs_length = to_meters(cable.length, cable.length_unit) + + Cable.objects.bulk_update(cables, ['_abs_length'], batch_size=100) + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0143_remove_primary_for_related_name'), + ] + + operations = [ + migrations.RunPython( + code=recalculate_abs_length, + reverse_code=migrations.RunPython.noop + ), + ] diff --git a/netbox/dcim/migrations/0145_site_remove_deprecated_fields.py b/netbox/dcim/migrations/0145_site_remove_deprecated_fields.py new file mode 100644 index 000000000..86918447d --- /dev/null +++ b/netbox/dcim/migrations/0145_site_remove_deprecated_fields.py @@ -0,0 +1,59 @@ +import os + +from django.db import migrations +from django.db.utils import DataError + + +def check_legacy_data(apps, schema_editor): + """ + Abort the migration if any legacy site fields still contain data. + """ + Site = apps.get_model('dcim', 'Site') + + site_count = Site.objects.exclude(asn__isnull=True).count() + if site_count and 'NETBOX_DELETE_LEGACY_DATA' not in os.environ: + raise DataError( + f"Unable to proceed with deleting asn field from Site model: Found {site_count} sites with " + f"legacy ASN data. Please ensure all legacy site ASN data has been migrated to ASN objects " + f"before proceeding. Or, set the NETBOX_DELETE_LEGACY_DATA environment variable to bypass " + f"this safeguard and delete all legacy site ASN data." + ) + + site_count = Site.objects.exclude(contact_name='', contact_phone='', contact_email='').count() + if site_count and 'NETBOX_DELETE_LEGACY_DATA' not in os.environ: + raise DataError( + f"Unable to proceed with deleting contact fields from Site model: Found {site_count} sites " + f"with legacy contact data. Please ensure all legacy site contact data has been migrated to " + f"contact objects before proceeding. Or, set the NETBOX_DELETE_LEGACY_DATA environment " + f"variable to bypass this safeguard and delete all legacy site contact data." + ) + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0144_fix_cable_abs_length'), + ] + + operations = [ + migrations.RunPython( + code=check_legacy_data, + reverse_code=migrations.RunPython.noop + ), + migrations.RemoveField( + model_name='site', + name='asn', + ), + migrations.RemoveField( + model_name='site', + name='contact_email', + ), + migrations.RemoveField( + model_name='site', + name='contact_name', + ), + migrations.RemoveField( + model_name='site', + name='contact_phone', + ), + ] diff --git a/netbox/dcim/migrations/0146_modules.py b/netbox/dcim/migrations/0146_modules.py new file mode 100644 index 000000000..821cf6119 --- /dev/null +++ b/netbox/dcim/migrations/0146_modules.py @@ -0,0 +1,279 @@ +from utilities.json import CustomFieldJSONEncoder +from django.db import migrations, models +import django.db.models.deletion +import taggit.managers +import utilities.fields +import utilities.ordering + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0066_customfield_name_validation'), + ('dcim', '0145_site_remove_deprecated_fields'), + ] + + operations = [ + # Rename any indexes left over from the old Module model (now InventoryItem) (#8656) + migrations.RunSQL( + """ + DO $$ + DECLARE + idx record; + BEGIN + FOR idx IN + SELECT indexname AS old_name, + replace(indexname, 'module', 'inventoryitem') AS new_name + FROM pg_indexes + WHERE schemaname = 'public' AND + tablename = 'dcim_inventoryitem' AND + indexname LIKE 'dcim_module_%' + LOOP + EXECUTE format( + 'ALTER INDEX %I RENAME TO %I;', + idx.old_name, + idx.new_name + ); + END LOOP; + END$$; + """ + ), + + migrations.AlterModelOptions( + name='consoleporttemplate', + options={'ordering': ('device_type', 'module_type', '_name')}, + ), + migrations.AlterModelOptions( + name='consoleserverporttemplate', + options={'ordering': ('device_type', 'module_type', '_name')}, + ), + migrations.AlterModelOptions( + name='frontporttemplate', + options={'ordering': ('device_type', 'module_type', '_name')}, + ), + migrations.AlterModelOptions( + name='interfacetemplate', + options={'ordering': ('device_type', 'module_type', '_name')}, + ), + migrations.AlterModelOptions( + name='poweroutlettemplate', + options={'ordering': ('device_type', 'module_type', '_name')}, + ), + migrations.AlterModelOptions( + name='powerporttemplate', + options={'ordering': ('device_type', 'module_type', '_name')}, + ), + migrations.AlterModelOptions( + name='rearporttemplate', + options={'ordering': ('device_type', 'module_type', '_name')}, + ), + migrations.AlterField( + model_name='consoleporttemplate', + name='device_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), + ), + migrations.AlterField( + model_name='consoleserverporttemplate', + name='device_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), + ), + migrations.AlterField( + model_name='frontporttemplate', + name='device_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), + ), + migrations.AlterField( + model_name='interfacetemplate', + name='device_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), + ), + migrations.AlterField( + model_name='poweroutlettemplate', + name='device_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), + ), + migrations.AlterField( + model_name='powerporttemplate', + name='device_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), + ), + migrations.AlterField( + model_name='rearporttemplate', + name='device_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), + ), + migrations.CreateModel( + name='ModuleType', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('model', models.CharField(max_length=100)), + ('part_number', models.CharField(blank=True, max_length=50)), + ('comments', models.TextField(blank=True)), + ('manufacturer', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='module_types', to='dcim.manufacturer')), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ], + options={ + 'ordering': ('manufacturer', 'model'), + 'unique_together': {('manufacturer', 'model')}, + }, + ), + migrations.CreateModel( + name='ModuleBay', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=64)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), + ('label', models.CharField(blank=True, max_length=64)), + ('position', models.CharField(blank=True, max_length=30)), + ('description', models.CharField(blank=True, max_length=200)), + ('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device')), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ], + options={ + 'ordering': ('device', '_name'), + 'unique_together': {('device', 'name')}, + }, + ), + migrations.CreateModel( + name='Module', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('local_context_data', models.JSONField(blank=True, null=True)), + ('serial', models.CharField(blank=True, max_length=50)), + ('asset_tag', models.CharField(blank=True, max_length=50, null=True, unique=True)), + ('comments', models.TextField(blank=True)), + ('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='modules', to='dcim.device')), + ('module_bay', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='installed_module', to='dcim.modulebay')), + ('module_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='instances', to='dcim.moduletype')), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ], + options={ + 'ordering': ('module_bay',), + }, + ), + migrations.AddField( + model_name='consoleport', + name='module', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.module'), + ), + migrations.AddField( + model_name='consoleporttemplate', + name='module_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'), + ), + migrations.AddField( + model_name='consoleserverport', + name='module', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.module'), + ), + migrations.AddField( + model_name='consoleserverporttemplate', + name='module_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'), + ), + migrations.AddField( + model_name='frontport', + name='module', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.module'), + ), + migrations.AddField( + model_name='frontporttemplate', + name='module_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'), + ), + migrations.AddField( + model_name='interface', + name='module', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.module'), + ), + migrations.AddField( + model_name='interfacetemplate', + name='module_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'), + ), + migrations.AddField( + model_name='poweroutlet', + name='module', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.module'), + ), + migrations.AddField( + model_name='poweroutlettemplate', + name='module_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'), + ), + migrations.AddField( + model_name='powerport', + name='module', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.module'), + ), + migrations.AddField( + model_name='powerporttemplate', + name='module_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'), + ), + migrations.AddField( + model_name='rearport', + name='module', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.module'), + ), + migrations.AddField( + model_name='rearporttemplate', + name='module_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'), + ), + migrations.AlterUniqueTogether( + name='consoleporttemplate', + unique_together={('device_type', 'name'), ('module_type', 'name')}, + ), + migrations.AlterUniqueTogether( + name='consoleserverporttemplate', + unique_together={('device_type', 'name'), ('module_type', 'name')}, + ), + migrations.AlterUniqueTogether( + name='frontporttemplate', + unique_together={('device_type', 'name'), ('rear_port', 'rear_port_position'), ('module_type', 'name')}, + ), + migrations.AlterUniqueTogether( + name='interfacetemplate', + unique_together={('device_type', 'name'), ('module_type', 'name')}, + ), + migrations.AlterUniqueTogether( + name='poweroutlettemplate', + unique_together={('device_type', 'name'), ('module_type', 'name')}, + ), + migrations.AlterUniqueTogether( + name='powerporttemplate', + unique_together={('device_type', 'name'), ('module_type', 'name')}, + ), + migrations.AlterUniqueTogether( + name='rearporttemplate', + unique_together={('device_type', 'name'), ('module_type', 'name')}, + ), + migrations.CreateModel( + name='ModuleBayTemplate', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=64)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), + ('label', models.CharField(blank=True, max_length=64)), + ('position', models.CharField(blank=True, max_length=30)), + ('description', models.CharField(blank=True, max_length=200)), + ('device_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype')), + ], + options={ + 'ordering': ('device_type', '_name'), + 'unique_together': {('device_type', 'name')}, + }, + ), + ] diff --git a/netbox/dcim/migrations/0147_inventoryitemrole.py b/netbox/dcim/migrations/0147_inventoryitemrole.py new file mode 100644 index 000000000..4b6c27450 --- /dev/null +++ b/netbox/dcim/migrations/0147_inventoryitemrole.py @@ -0,0 +1,38 @@ +from utilities.json import CustomFieldJSONEncoder +from django.db import migrations, models +import django.db.models.deletion +import taggit.managers +import utilities.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0068_configcontext_cluster_types'), + ('dcim', '0146_modules'), + ] + + operations = [ + migrations.CreateModel( + name='InventoryItemRole', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, unique=True)), + ('slug', models.SlugField(max_length=100, unique=True)), + ('color', utilities.fields.ColorField(default='9e9e9e', max_length=6)), + ('description', models.CharField(blank=True, max_length=200)), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ], + options={ + 'ordering': ('name',), + }, + ), + migrations.AddField( + model_name='inventoryitem', + name='role', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='inventory_items', to='dcim.inventoryitemrole'), + ), + ] diff --git a/netbox/dcim/migrations/0148_inventoryitem_component.py b/netbox/dcim/migrations/0148_inventoryitem_component.py new file mode 100644 index 000000000..a18f41d3d --- /dev/null +++ b/netbox/dcim/migrations/0148_inventoryitem_component.py @@ -0,0 +1,23 @@ +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('dcim', '0147_inventoryitemrole'), + ] + + operations = [ + migrations.AddField( + model_name='inventoryitem', + name='component_id', + field=models.PositiveBigIntegerField(blank=True, null=True), + ), + migrations.AddField( + model_name='inventoryitem', + name='component_type', + field=models.ForeignKey(blank=True, limit_choices_to=models.Q(('app_label', 'dcim'), ('model__in', ('consoleport', 'consoleserverport', 'frontport', 'interface', 'poweroutlet', 'powerport', 'rearport'))), null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype'), + ), + ] diff --git a/netbox/dcim/migrations/0149_inventoryitem_templates.py b/netbox/dcim/migrations/0149_inventoryitem_templates.py new file mode 100644 index 000000000..f0b1f3cff --- /dev/null +++ b/netbox/dcim/migrations/0149_inventoryitem_templates.py @@ -0,0 +1,43 @@ +from django.db import migrations, models +import django.db.models.deletion +import mptt.fields +import utilities.fields +import utilities.ordering + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('dcim', '0148_inventoryitem_component'), + ] + + operations = [ + migrations.CreateModel( + name='InventoryItemTemplate', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=64)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), + ('label', models.CharField(blank=True, max_length=64)), + ('description', models.CharField(blank=True, max_length=200)), + ('component_id', models.PositiveBigIntegerField(blank=True, null=True)), + ('part_id', models.CharField(blank=True, max_length=50)), + ('lft', models.PositiveIntegerField(editable=False)), + ('rght', models.PositiveIntegerField(editable=False)), + ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), + ('level', models.PositiveIntegerField(editable=False)), + ('component_type', models.ForeignKey(blank=True, limit_choices_to=models.Q(('app_label', 'dcim'), ('model__in', ('consoleporttemplate', 'consoleserverporttemplate', 'frontporttemplate', 'interfacetemplate', 'poweroutlettemplate', 'powerporttemplate', 'rearporttemplate'))), null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype')), + ('device_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype')), + ('manufacturer', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='inventory_item_templates', to='dcim.manufacturer')), + ('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='child_items', to='dcim.inventoryitemtemplate')), + ('role', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='inventory_item_templates', to='dcim.inventoryitemrole')), + ], + options={ + 'ordering': ('device_type__id', 'parent__id', '_name'), + 'unique_together': {('device_type', 'parent', 'name')}, + }, + ), + ] diff --git a/netbox/dcim/migrations/0150_interface_vrf.py b/netbox/dcim/migrations/0150_interface_vrf.py new file mode 100644 index 000000000..f8741e4a0 --- /dev/null +++ b/netbox/dcim/migrations/0150_interface_vrf.py @@ -0,0 +1,20 @@ +# Generated by Django 3.2.11 on 2022-01-07 18:34 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0054_vlangroup_min_max_vids'), + ('dcim', '0149_inventoryitem_templates'), + ] + + operations = [ + migrations.AddField( + model_name='interface', + name='vrf', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='interfaces', to='ipam.vrf'), + ), + ] diff --git a/netbox/dcim/migrations/0151_interface_speed_duplex.py b/netbox/dcim/migrations/0151_interface_speed_duplex.py new file mode 100644 index 000000000..7e800f42a --- /dev/null +++ b/netbox/dcim/migrations/0151_interface_speed_duplex.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.10 on 2022-01-08 18:23 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0150_interface_vrf'), + ] + + operations = [ + migrations.AddField( + model_name='interface', + name='duplex', + field=models.CharField(blank=True, max_length=50, null=True), + ), + migrations.AddField( + model_name='interface', + name='speed', + field=models.PositiveIntegerField(blank=True, null=True), + ), + ] diff --git a/netbox/dcim/migrations/0152_standardize_id_fields.py b/netbox/dcim/migrations/0152_standardize_id_fields.py new file mode 100644 index 000000000..6bf5b43f4 --- /dev/null +++ b/netbox/dcim/migrations/0152_standardize_id_fields.py @@ -0,0 +1,274 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0151_interface_speed_duplex'), + ] + + operations = [ + # Model IDs + migrations.AlterField( + model_name='cable', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='cablepath', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='consoleport', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='consoleporttemplate', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='consoleserverport', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='consoleserverporttemplate', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='device', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='devicebay', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='devicebaytemplate', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='devicerole', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='devicetype', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='frontport', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='frontporttemplate', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='interface', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='interfacetemplate', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='inventoryitem', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='inventoryitemrole', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='inventoryitemtemplate', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='location', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='manufacturer', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='module', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='modulebay', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='modulebaytemplate', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='moduletype', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='platform', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='powerfeed', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='poweroutlet', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='poweroutlettemplate', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='powerpanel', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='powerport', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='powerporttemplate', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='rack', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='rackreservation', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='rackrole', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='rearport', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='rearporttemplate', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='region', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='site', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='sitegroup', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='virtualchassis', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + + # GFK IDs + migrations.AlterField( + model_name='cable', + name='termination_a_id', + field=models.PositiveBigIntegerField(), + ), + migrations.AlterField( + model_name='cable', + name='termination_b_id', + field=models.PositiveBigIntegerField(), + ), + migrations.AlterField( + model_name='cablepath', + name='destination_id', + field=models.PositiveBigIntegerField(blank=True, null=True), + ), + migrations.AlterField( + model_name='cablepath', + name='origin_id', + field=models.PositiveBigIntegerField(), + ), + migrations.AlterField( + model_name='consoleport', + name='_link_peer_id', + field=models.PositiveBigIntegerField(blank=True, null=True), + ), + migrations.AlterField( + model_name='consoleserverport', + name='_link_peer_id', + field=models.PositiveBigIntegerField(blank=True, null=True), + ), + migrations.AlterField( + model_name='frontport', + name='_link_peer_id', + field=models.PositiveBigIntegerField(blank=True, null=True), + ), + migrations.AlterField( + model_name='interface', + name='_link_peer_id', + field=models.PositiveBigIntegerField(blank=True, null=True), + ), + migrations.AlterField( + model_name='powerfeed', + name='_link_peer_id', + field=models.PositiveBigIntegerField(blank=True, null=True), + ), + migrations.AlterField( + model_name='poweroutlet', + name='_link_peer_id', + field=models.PositiveBigIntegerField(blank=True, null=True), + ), + migrations.AlterField( + model_name='powerport', + name='_link_peer_id', + field=models.PositiveBigIntegerField(blank=True, null=True), + ), + migrations.AlterField( + model_name='rearport', + name='_link_peer_id', + field=models.PositiveBigIntegerField(blank=True, null=True), + ), + ] diff --git a/netbox/dcim/migrations/0153_created_datetimefield.py b/netbox/dcim/migrations/0153_created_datetimefield.py new file mode 100644 index 000000000..c1cc4132e --- /dev/null +++ b/netbox/dcim/migrations/0153_created_datetimefield.py @@ -0,0 +1,208 @@ +# Generated by Django 4.0.2 on 2022-02-08 18:54 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0152_standardize_id_fields'), + ] + + operations = [ + migrations.AlterField( + model_name='cable', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='consoleport', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='consoleporttemplate', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='consoleserverport', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='consoleserverporttemplate', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='device', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='devicebay', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='devicebaytemplate', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='devicerole', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='devicetype', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='frontport', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='frontporttemplate', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='interface', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='interfacetemplate', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='inventoryitem', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='inventoryitemrole', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='inventoryitemtemplate', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='location', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='manufacturer', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='module', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='modulebay', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='modulebaytemplate', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='moduletype', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='platform', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='powerfeed', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='poweroutlet', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='poweroutlettemplate', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='powerpanel', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='powerport', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='powerporttemplate', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='rack', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='rackreservation', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='rackrole', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='rearport', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='rearporttemplate', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='region', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='site', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='sitegroup', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='virtualchassis', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + ] diff --git a/netbox/dcim/migrations/0154_half_height_rack_units.py b/netbox/dcim/migrations/0154_half_height_rack_units.py new file mode 100644 index 000000000..f212aa21a --- /dev/null +++ b/netbox/dcim/migrations/0154_half_height_rack_units.py @@ -0,0 +1,23 @@ +import django.contrib.postgres.fields +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0153_created_datetimefield'), + ] + + operations = [ + migrations.AlterField( + model_name='devicetype', + name='u_height', + field=models.DecimalField(decimal_places=1, default=1.0, max_digits=4), + ), + migrations.AlterField( + model_name='device', + name='position', + field=models.DecimalField(blank=True, decimal_places=1, max_digits=4, null=True, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(100.5)]), + ), + ] diff --git a/netbox/dcim/migrations/0155_interface_poe_mode_type.py b/netbox/dcim/migrations/0155_interface_poe_mode_type.py new file mode 100644 index 000000000..13f2ddfc0 --- /dev/null +++ b/netbox/dcim/migrations/0155_interface_poe_mode_type.py @@ -0,0 +1,33 @@ +# Generated by Django 4.0.5 on 2022-06-22 00:36 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0154_half_height_rack_units'), + ] + + operations = [ + migrations.AddField( + model_name='interface', + name='poe_mode', + field=models.CharField(blank=True, max_length=50), + ), + migrations.AddField( + model_name='interface', + name='poe_type', + field=models.CharField(blank=True, max_length=50), + ), + migrations.AddField( + model_name='interfacetemplate', + name='poe_mode', + field=models.CharField(blank=True, max_length=50), + ), + migrations.AddField( + model_name='interfacetemplate', + name='poe_type', + field=models.CharField(blank=True, max_length=50), + ), + ] diff --git a/netbox/dcim/migrations/0156_location_status.py b/netbox/dcim/migrations/0156_location_status.py new file mode 100644 index 000000000..b20273755 --- /dev/null +++ b/netbox/dcim/migrations/0156_location_status.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0.5 on 2022-06-22 17:10 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0155_interface_poe_mode_type'), + ] + + operations = [ + migrations.AddField( + model_name='location', + name='status', + field=models.CharField(default='active', max_length=50), + ), + ] diff --git a/netbox/dcim/migrations/0157_new_cabling_models.py b/netbox/dcim/migrations/0157_new_cabling_models.py new file mode 100644 index 000000000..a3a650086 --- /dev/null +++ b/netbox/dcim/migrations/0157_new_cabling_models.py @@ -0,0 +1,95 @@ +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('dcim', '0156_location_status'), + ] + + operations = [ + + # Create CableTermination model + migrations.CreateModel( + name='CableTermination', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('cable_end', models.CharField(max_length=1)), + ('termination_id', models.PositiveBigIntegerField()), + ('cable', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='terminations', to='dcim.cable')), + ('termination_type', models.ForeignKey(limit_choices_to=models.Q(models.Q(models.Q(('app_label', 'circuits'), ('model__in', ('circuittermination',))), models.Q(('app_label', 'dcim'), ('model__in', ('consoleport', 'consoleserverport', 'frontport', 'interface', 'powerfeed', 'poweroutlet', 'powerport', 'rearport'))), _connector='OR')), on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype')), + ('_device', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dcim.device')), + ('_rack', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dcim.rack')), + ('_location', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dcim.location')), + ('_site', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dcim.site')), + ], + options={ + 'ordering': ('cable', 'cable_end', 'pk'), + }, + ), + migrations.AddConstraint( + model_name='cabletermination', + constraint=models.UniqueConstraint(fields=('termination_type', 'termination_id'), name='dcim_cable_termination_unique_termination'), + ), + + # Update CablePath model + migrations.RenameField( + model_name='cablepath', + old_name='path', + new_name='_nodes', + ), + migrations.AddField( + model_name='cablepath', + name='path', + field=models.JSONField(default=list), + ), + migrations.AddField( + model_name='cablepath', + name='is_complete', + field=models.BooleanField(default=False), + ), + + # Add cable_end field to cable termination models + migrations.AddField( + model_name='consoleport', + name='cable_end', + field=models.CharField(blank=True, max_length=1), + ), + migrations.AddField( + model_name='consoleserverport', + name='cable_end', + field=models.CharField(blank=True, max_length=1), + ), + migrations.AddField( + model_name='frontport', + name='cable_end', + field=models.CharField(blank=True, max_length=1), + ), + migrations.AddField( + model_name='interface', + name='cable_end', + field=models.CharField(blank=True, max_length=1), + ), + migrations.AddField( + model_name='powerfeed', + name='cable_end', + field=models.CharField(blank=True, max_length=1), + ), + migrations.AddField( + model_name='poweroutlet', + name='cable_end', + field=models.CharField(blank=True, max_length=1), + ), + migrations.AddField( + model_name='powerport', + name='cable_end', + field=models.CharField(blank=True, max_length=1), + ), + migrations.AddField( + model_name='rearport', + name='cable_end', + field=models.CharField(blank=True, max_length=1), + ), + ] diff --git a/netbox/dcim/migrations/0158_populate_cable_terminations.py b/netbox/dcim/migrations/0158_populate_cable_terminations.py new file mode 100644 index 000000000..72d7f154a --- /dev/null +++ b/netbox/dcim/migrations/0158_populate_cable_terminations.py @@ -0,0 +1,87 @@ +import sys + +from django.db import migrations + + +def cache_related_objects(termination): + """ + Replicate caching logic from CableTermination.cache_related_objects() + """ + attrs = {} + + # Device components + if getattr(termination, 'device', None): + attrs['_device'] = termination.device + attrs['_rack'] = termination.device.rack + attrs['_location'] = termination.device.location + attrs['_site'] = termination.device.site + + # Power feeds + elif getattr(termination, 'rack', None): + attrs['_rack'] = termination.rack + attrs['_location'] = termination.rack.location + attrs['_site'] = termination.rack.site + + # Circuit terminations + elif getattr(termination, 'site', None): + attrs['_site'] = termination.site + + return attrs + + +def populate_cable_terminations(apps, schema_editor): + """ + Replicate terminations from the Cable model into CableTermination instances. + """ + ContentType = apps.get_model('contenttypes', 'ContentType') + Cable = apps.get_model('dcim', 'Cable') + CableTermination = apps.get_model('dcim', 'CableTermination') + + # Retrieve the necessary data from Cable objects + cables = Cable.objects.values( + 'id', 'termination_a_type', 'termination_a_id', 'termination_b_type', 'termination_b_id' + ) + + # Queue CableTerminations to be created + cable_terminations = [] + cable_count = cables.count() + for i, cable in enumerate(cables, start=1): + for cable_end in ('a', 'b'): + # We must manually instantiate the termination object, because GFK fields are not + # supported within migrations. + termination_ct = ContentType.objects.get(pk=cable[f'termination_{cable_end}_type']) + termination_model = apps.get_model(termination_ct.app_label, termination_ct.model) + termination = termination_model.objects.get(pk=cable[f'termination_{cable_end}_id']) + + cable_terminations.append(CableTermination( + cable_id=cable['id'], + cable_end=cable_end.upper(), + termination_type_id=cable[f'termination_{cable_end}_type'], + termination_id=cable[f'termination_{cable_end}_id'], + **cache_related_objects(termination) + )) + + # Output progress occasionally + if 'test' not in sys.argv and not i % 100: + progress = float(i) * 100 / cable_count + if i == 100: + print('') + sys.stdout.write(f"\r Updated {i}/{cable_count} cables ({progress:.2f}%)") + sys.stdout.flush() + + # Bulk create the termination objects + CableTermination.objects.bulk_create(cable_terminations, batch_size=100) + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0157_new_cabling_models'), + ] + + operations = [ + migrations.RunPython( + code=populate_cable_terminations, + reverse_code=migrations.RunPython.noop + ), + ] diff --git a/netbox/dcim/migrations/0159_populate_cable_paths.py b/netbox/dcim/migrations/0159_populate_cable_paths.py new file mode 100644 index 000000000..22fe4b67e --- /dev/null +++ b/netbox/dcim/migrations/0159_populate_cable_paths.py @@ -0,0 +1,50 @@ +from django.db import migrations + +from dcim.utils import compile_path_node + + +def populate_cable_paths(apps, schema_editor): + """ + Replicate terminations from the Cable model into CableTermination instances. + """ + CablePath = apps.get_model('dcim', 'CablePath') + + # Construct the new two-dimensional path, and add the origin & destination objects to the nodes list + cable_paths = [] + for cablepath in CablePath.objects.all(): + + # Origin + origin = compile_path_node(cablepath.origin_type_id, cablepath.origin_id) + cablepath.path.append([origin]) + cablepath._nodes.insert(0, origin) + + # Transit nodes + cablepath.path.extend([ + [node] for node in cablepath._nodes[1:] + ]) + + # Destination + if cablepath.destination_id: + destination = compile_path_node(cablepath.destination_type_id, cablepath.destination_id) + cablepath.path.append([destination]) + cablepath._nodes.append(destination) + cablepath.is_complete = True + + cable_paths.append(cablepath) + + # Bulk update all CableTerminations + CablePath.objects.bulk_update(cable_paths, fields=('path', '_nodes', 'is_complete'), batch_size=100) + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0158_populate_cable_terminations'), + ] + + operations = [ + migrations.RunPython( + code=populate_cable_paths, + reverse_code=migrations.RunPython.noop + ), + ] diff --git a/netbox/dcim/migrations/0160_populate_cable_ends.py b/netbox/dcim/migrations/0160_populate_cable_ends.py new file mode 100644 index 000000000..53e042abc --- /dev/null +++ b/netbox/dcim/migrations/0160_populate_cable_ends.py @@ -0,0 +1,46 @@ +from django.db import migrations + + +def populate_cable_terminations(apps, schema_editor): + Cable = apps.get_model('dcim', 'Cable') + + cable_termination_models = ( + apps.get_model('dcim', 'ConsolePort'), + apps.get_model('dcim', 'ConsoleServerPort'), + apps.get_model('dcim', 'PowerPort'), + apps.get_model('dcim', 'PowerOutlet'), + apps.get_model('dcim', 'Interface'), + apps.get_model('dcim', 'FrontPort'), + apps.get_model('dcim', 'RearPort'), + apps.get_model('dcim', 'PowerFeed'), + apps.get_model('circuits', 'CircuitTermination'), + ) + + for model in cable_termination_models: + model.objects.filter( + id__in=Cable.objects.filter( + termination_a_type__app_label=model._meta.app_label, + termination_a_type__model=model._meta.model_name + ).values_list('termination_a_id', flat=True) + ).update(cable_end='A') + model.objects.filter( + id__in=Cable.objects.filter( + termination_b_type__app_label=model._meta.app_label, + termination_b_type__model=model._meta.model_name + ).values_list('termination_b_id', flat=True) + ).update(cable_end='B') + + +class Migration(migrations.Migration): + + dependencies = [ + ('circuits', '0037_new_cabling_models'), + ('dcim', '0159_populate_cable_paths'), + ] + + operations = [ + migrations.RunPython( + code=populate_cable_terminations, + reverse_code=migrations.RunPython.noop + ), + ] diff --git a/netbox/dcim/migrations/0161_cabling_cleanup.py b/netbox/dcim/migrations/0161_cabling_cleanup.py new file mode 100644 index 000000000..8a1b7a09e --- /dev/null +++ b/netbox/dcim/migrations/0161_cabling_cleanup.py @@ -0,0 +1,134 @@ +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0160_populate_cable_ends'), + ] + + operations = [ + + # Remove old fields from Cable + migrations.AlterModelOptions( + name='cable', + options={'ordering': ('pk',)}, + ), + migrations.AlterUniqueTogether( + name='cable', + unique_together=set(), + ), + migrations.RemoveField( + model_name='cable', + name='termination_a_id', + ), + migrations.RemoveField( + model_name='cable', + name='termination_a_type', + ), + migrations.RemoveField( + model_name='cable', + name='termination_b_id', + ), + migrations.RemoveField( + model_name='cable', + name='termination_b_type', + ), + migrations.RemoveField( + model_name='cable', + name='_termination_a_device', + ), + migrations.RemoveField( + model_name='cable', + name='_termination_b_device', + ), + + # Remove old fields from CablePath + migrations.AlterUniqueTogether( + name='cablepath', + unique_together=set(), + ), + migrations.RemoveField( + model_name='cablepath', + name='destination_id', + ), + migrations.RemoveField( + model_name='cablepath', + name='destination_type', + ), + migrations.RemoveField( + model_name='cablepath', + name='origin_id', + ), + migrations.RemoveField( + model_name='cablepath', + name='origin_type', + ), + + # Remove link peer type/ID fields from cable termination models + migrations.RemoveField( + model_name='consoleport', + name='_link_peer_id', + ), + migrations.RemoveField( + model_name='consoleport', + name='_link_peer_type', + ), + migrations.RemoveField( + model_name='consoleserverport', + name='_link_peer_id', + ), + migrations.RemoveField( + model_name='consoleserverport', + name='_link_peer_type', + ), + migrations.RemoveField( + model_name='frontport', + name='_link_peer_id', + ), + migrations.RemoveField( + model_name='frontport', + name='_link_peer_type', + ), + migrations.RemoveField( + model_name='interface', + name='_link_peer_id', + ), + migrations.RemoveField( + model_name='interface', + name='_link_peer_type', + ), + migrations.RemoveField( + model_name='powerfeed', + name='_link_peer_id', + ), + migrations.RemoveField( + model_name='powerfeed', + name='_link_peer_type', + ), + migrations.RemoveField( + model_name='poweroutlet', + name='_link_peer_id', + ), + migrations.RemoveField( + model_name='poweroutlet', + name='_link_peer_type', + ), + migrations.RemoveField( + model_name='powerport', + name='_link_peer_id', + ), + migrations.RemoveField( + model_name='powerport', + name='_link_peer_type', + ), + migrations.RemoveField( + model_name='rearport', + name='_link_peer_id', + ), + migrations.RemoveField( + model_name='rearport', + name='_link_peer_type', + ), + + ] diff --git a/netbox/dcim/migrations/0162_unique_constraints.py b/netbox/dcim/migrations/0162_unique_constraints.py new file mode 100644 index 000000000..d52dbb6c9 --- /dev/null +++ b/netbox/dcim/migrations/0162_unique_constraints.py @@ -0,0 +1,332 @@ +from django.db import migrations, models +import django.db.models.functions.text + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0161_cabling_cleanup'), + ] + + operations = [ + migrations.RemoveConstraint( + model_name='cabletermination', + name='dcim_cable_termination_unique_termination', + ), + migrations.RemoveConstraint( + model_name='location', + name='dcim_location_name', + ), + migrations.RemoveConstraint( + model_name='location', + name='dcim_location_slug', + ), + migrations.RemoveConstraint( + model_name='region', + name='dcim_region_name', + ), + migrations.RemoveConstraint( + model_name='region', + name='dcim_region_slug', + ), + migrations.RemoveConstraint( + model_name='sitegroup', + name='dcim_sitegroup_name', + ), + migrations.RemoveConstraint( + model_name='sitegroup', + name='dcim_sitegroup_slug', + ), + migrations.AlterUniqueTogether( + name='consoleport', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='consoleporttemplate', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='consoleserverport', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='consoleserverporttemplate', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='device', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='devicebay', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='devicebaytemplate', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='devicetype', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='frontport', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='frontporttemplate', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='interface', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='interfacetemplate', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='inventoryitem', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='inventoryitemtemplate', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='modulebay', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='modulebaytemplate', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='moduletype', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='powerfeed', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='poweroutlet', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='poweroutlettemplate', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='powerpanel', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='powerport', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='powerporttemplate', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='rack', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='rearport', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='rearporttemplate', + unique_together=set(), + ), + migrations.AddConstraint( + model_name='cabletermination', + constraint=models.UniqueConstraint(fields=('termination_type', 'termination_id'), name='dcim_cabletermination_unique_termination'), + ), + migrations.AddConstraint( + model_name='consoleport', + constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_consoleport_unique_device_name'), + ), + migrations.AddConstraint( + model_name='consoleporttemplate', + constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_consoleporttemplate_unique_device_type_name'), + ), + migrations.AddConstraint( + model_name='consoleporttemplate', + constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_consoleporttemplate_unique_module_type_name'), + ), + migrations.AddConstraint( + model_name='consoleserverport', + constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_consoleserverport_unique_device_name'), + ), + migrations.AddConstraint( + model_name='consoleserverporttemplate', + constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_consoleserverporttemplate_unique_device_type_name'), + ), + migrations.AddConstraint( + model_name='consoleserverporttemplate', + constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_consoleserverporttemplate_unique_module_type_name'), + ), + migrations.AddConstraint( + model_name='device', + constraint=models.UniqueConstraint(django.db.models.functions.text.Lower('name'), models.F('site'), models.F('tenant'), name='dcim_device_unique_name_site_tenant'), + ), + migrations.AddConstraint( + model_name='device', + constraint=models.UniqueConstraint(django.db.models.functions.text.Lower('name'), models.F('site'), condition=models.Q(('tenant__isnull', True)), name='dcim_device_unique_name_site', violation_error_message='Device name must be unique per site.'), + ), + migrations.AddConstraint( + model_name='device', + constraint=models.UniqueConstraint(fields=('rack', 'position', 'face'), name='dcim_device_unique_rack_position_face'), + ), + migrations.AddConstraint( + model_name='device', + constraint=models.UniqueConstraint(fields=('virtual_chassis', 'vc_position'), name='dcim_device_unique_virtual_chassis_vc_position'), + ), + migrations.AddConstraint( + model_name='devicebay', + constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_devicebay_unique_device_name'), + ), + migrations.AddConstraint( + model_name='devicebaytemplate', + constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_devicebaytemplate_unique_device_type_name'), + ), + migrations.AddConstraint( + model_name='devicetype', + constraint=models.UniqueConstraint(fields=('manufacturer', 'model'), name='dcim_devicetype_unique_manufacturer_model'), + ), + migrations.AddConstraint( + model_name='devicetype', + constraint=models.UniqueConstraint(fields=('manufacturer', 'slug'), name='dcim_devicetype_unique_manufacturer_slug'), + ), + migrations.AddConstraint( + model_name='frontport', + constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_frontport_unique_device_name'), + ), + migrations.AddConstraint( + model_name='frontport', + constraint=models.UniqueConstraint(fields=('rear_port', 'rear_port_position'), name='dcim_frontport_unique_rear_port_position'), + ), + migrations.AddConstraint( + model_name='frontporttemplate', + constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_frontporttemplate_unique_device_type_name'), + ), + migrations.AddConstraint( + model_name='frontporttemplate', + constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_frontporttemplate_unique_module_type_name'), + ), + migrations.AddConstraint( + model_name='frontporttemplate', + constraint=models.UniqueConstraint(fields=('rear_port', 'rear_port_position'), name='dcim_frontporttemplate_unique_rear_port_position'), + ), + migrations.AddConstraint( + model_name='interface', + constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_interface_unique_device_name'), + ), + migrations.AddConstraint( + model_name='interfacetemplate', + constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_interfacetemplate_unique_device_type_name'), + ), + migrations.AddConstraint( + model_name='interfacetemplate', + constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_interfacetemplate_unique_module_type_name'), + ), + migrations.AddConstraint( + model_name='inventoryitem', + constraint=models.UniqueConstraint(fields=('device', 'parent', 'name'), name='dcim_inventoryitem_unique_device_parent_name'), + ), + migrations.AddConstraint( + model_name='inventoryitemtemplate', + constraint=models.UniqueConstraint(fields=('device_type', 'parent', 'name'), name='dcim_inventoryitemtemplate_unique_device_type_parent_name'), + ), + migrations.AddConstraint( + model_name='location', + constraint=models.UniqueConstraint(condition=models.Q(('parent__isnull', True)), fields=('site', 'name'), name='dcim_location_name', violation_error_message='A location with this name already exists within the specified site.'), + ), + migrations.AddConstraint( + model_name='location', + constraint=models.UniqueConstraint(condition=models.Q(('parent__isnull', True)), fields=('site', 'slug'), name='dcim_location_slug', violation_error_message='A location with this slug already exists within the specified site.'), + ), + migrations.AddConstraint( + model_name='modulebay', + constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_modulebay_unique_device_name'), + ), + migrations.AddConstraint( + model_name='modulebaytemplate', + constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_modulebaytemplate_unique_device_type_name'), + ), + migrations.AddConstraint( + model_name='moduletype', + constraint=models.UniqueConstraint(fields=('manufacturer', 'model'), name='dcim_moduletype_unique_manufacturer_model'), + ), + migrations.AddConstraint( + model_name='powerfeed', + constraint=models.UniqueConstraint(fields=('power_panel', 'name'), name='dcim_powerfeed_unique_power_panel_name'), + ), + migrations.AddConstraint( + model_name='poweroutlet', + constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_poweroutlet_unique_device_name'), + ), + migrations.AddConstraint( + model_name='poweroutlettemplate', + constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_poweroutlettemplate_unique_device_type_name'), + ), + migrations.AddConstraint( + model_name='poweroutlettemplate', + constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_poweroutlettemplate_unique_module_type_name'), + ), + migrations.AddConstraint( + model_name='powerpanel', + constraint=models.UniqueConstraint(fields=('site', 'name'), name='dcim_powerpanel_unique_site_name'), + ), + migrations.AddConstraint( + model_name='powerport', + constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_powerport_unique_device_name'), + ), + migrations.AddConstraint( + model_name='powerporttemplate', + constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_powerporttemplate_unique_device_type_name'), + ), + migrations.AddConstraint( + model_name='powerporttemplate', + constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_powerporttemplate_unique_module_type_name'), + ), + migrations.AddConstraint( + model_name='rack', + constraint=models.UniqueConstraint(fields=('location', 'name'), name='dcim_rack_unique_location_name'), + ), + migrations.AddConstraint( + model_name='rack', + constraint=models.UniqueConstraint(fields=('location', 'facility_id'), name='dcim_rack_unique_location_facility_id'), + ), + migrations.AddConstraint( + model_name='rearport', + constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_rearport_unique_device_name'), + ), + migrations.AddConstraint( + model_name='rearporttemplate', + constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_rearporttemplate_unique_device_type_name'), + ), + migrations.AddConstraint( + model_name='rearporttemplate', + constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_rearporttemplate_unique_module_type_name'), + ), + migrations.AddConstraint( + model_name='region', + constraint=models.UniqueConstraint(condition=models.Q(('parent__isnull', True)), fields=('name',), name='dcim_region_name', violation_error_message='A top-level region with this name already exists.'), + ), + migrations.AddConstraint( + model_name='region', + constraint=models.UniqueConstraint(condition=models.Q(('parent__isnull', True)), fields=('slug',), name='dcim_region_slug', violation_error_message='A top-level region with this slug already exists.'), + ), + migrations.AddConstraint( + model_name='sitegroup', + constraint=models.UniqueConstraint(condition=models.Q(('parent__isnull', True)), fields=('name',), name='dcim_sitegroup_name', violation_error_message='A top-level site group with this name already exists.'), + ), + migrations.AddConstraint( + model_name='sitegroup', + constraint=models.UniqueConstraint(condition=models.Q(('parent__isnull', True)), fields=('slug',), name='dcim_sitegroup_slug', violation_error_message='A top-level site group with this slug already exists.'), + ), + ] diff --git a/netbox/dcim/migrations/0163_weight_fields.py b/netbox/dcim/migrations/0163_weight_fields.py new file mode 100644 index 000000000..ddcc01164 --- /dev/null +++ b/netbox/dcim/migrations/0163_weight_fields.py @@ -0,0 +1,72 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0162_unique_constraints'), + ] + + operations = [ + + # Device types + migrations.AddField( + model_name='devicetype', + name='weight', + field=models.DecimalField(blank=True, decimal_places=2, max_digits=8, null=True), + ), + migrations.AddField( + model_name='devicetype', + name='weight_unit', + field=models.CharField(blank=True, max_length=50), + ), + migrations.AddField( + model_name='devicetype', + name='_abs_weight', + field=models.PositiveBigIntegerField(blank=True, null=True), + ), + + # Module types + migrations.AddField( + model_name='moduletype', + name='weight', + field=models.DecimalField(blank=True, decimal_places=2, max_digits=8, null=True), + ), + migrations.AddField( + model_name='moduletype', + name='weight_unit', + field=models.CharField(blank=True, max_length=50), + ), + migrations.AddField( + model_name='moduletype', + name='_abs_weight', + field=models.PositiveBigIntegerField(blank=True, null=True), + ), + + # Racks + migrations.AddField( + model_name='rack', + name='weight', + field=models.DecimalField(blank=True, decimal_places=2, max_digits=8, null=True), + ), + migrations.AddField( + model_name='rack', + name='max_weight', + field=models.PositiveIntegerField(blank=True, null=True), + ), + migrations.AddField( + model_name='rack', + name='weight_unit', + field=models.CharField(blank=True, max_length=50), + ), + migrations.AddField( + model_name='rack', + name='_abs_weight', + field=models.PositiveBigIntegerField(blank=True, null=True), + ), + migrations.AddField( + model_name='rack', + name='_abs_max_weight', + field=models.PositiveBigIntegerField(blank=True, null=True), + ), + ] diff --git a/netbox/dcim/migrations/0164_rack_mounting_depth.py b/netbox/dcim/migrations/0164_rack_mounting_depth.py new file mode 100644 index 000000000..96836e0d6 --- /dev/null +++ b/netbox/dcim/migrations/0164_rack_mounting_depth.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.1 on 2022-10-27 14:01 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0163_weight_fields'), + ] + + operations = [ + migrations.AddField( + model_name='rack', + name='mounting_depth', + field=models.PositiveSmallIntegerField(blank=True, null=True), + ), + ] diff --git a/netbox/dcim/migrations/0165_standardize_description_comments.py b/netbox/dcim/migrations/0165_standardize_description_comments.py new file mode 100644 index 000000000..f17f1d321 --- /dev/null +++ b/netbox/dcim/migrations/0165_standardize_description_comments.py @@ -0,0 +1,78 @@ +# Generated by Django 4.1.2 on 2022-11-03 18:24 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0164_rack_mounting_depth'), + ] + + operations = [ + migrations.AddField( + model_name='cable', + name='comments', + field=models.TextField(blank=True), + ), + migrations.AddField( + model_name='cable', + name='description', + field=models.CharField(blank=True, max_length=200), + ), + migrations.AddField( + model_name='device', + name='description', + field=models.CharField(blank=True, max_length=200), + ), + migrations.AddField( + model_name='devicetype', + name='description', + field=models.CharField(blank=True, max_length=200), + ), + migrations.AddField( + model_name='module', + name='description', + field=models.CharField(blank=True, max_length=200), + ), + migrations.AddField( + model_name='moduletype', + name='description', + field=models.CharField(blank=True, max_length=200), + ), + migrations.AddField( + model_name='powerfeed', + name='description', + field=models.CharField(blank=True, max_length=200), + ), + migrations.AddField( + model_name='powerpanel', + name='comments', + field=models.TextField(blank=True), + ), + migrations.AddField( + model_name='powerpanel', + name='description', + field=models.CharField(blank=True, max_length=200), + ), + migrations.AddField( + model_name='rack', + name='description', + field=models.CharField(blank=True, max_length=200), + ), + migrations.AddField( + model_name='rackreservation', + name='comments', + field=models.TextField(blank=True), + ), + migrations.AddField( + model_name='virtualchassis', + name='comments', + field=models.TextField(blank=True), + ), + migrations.AddField( + model_name='virtualchassis', + name='description', + field=models.CharField(blank=True, max_length=200), + ), + ] diff --git a/netbox/dcim/migrations/0166_virtualdevicecontext.py b/netbox/dcim/migrations/0166_virtualdevicecontext.py new file mode 100644 index 000000000..05becbdc6 --- /dev/null +++ b/netbox/dcim/migrations/0166_virtualdevicecontext.py @@ -0,0 +1,54 @@ +# Generated by Django 4.1.2 on 2022-11-10 16:56 + +from django.db import migrations, models +import django.db.models.deletion +import taggit.managers +import utilities.json + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0063_standardize_description_comments'), + ('extras', '0082_savedfilter'), + ('tenancy', '0009_standardize_description_comments'), + ('dcim', '0165_standardize_description_comments'), + ] + + operations = [ + migrations.CreateModel( + name='VirtualDeviceContext', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), + ('description', models.CharField(blank=True, max_length=200)), + ('name', models.CharField(max_length=64)), + ('status', models.CharField(max_length=50)), + ('identifier', models.PositiveSmallIntegerField(blank=True, null=True)), + ('comments', models.TextField(blank=True)), + ('device', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vdcs', to='dcim.device')), + ('primary_ip4', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='ipam.ipaddress')), + ('primary_ip6', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='ipam.ipaddress')), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ('tenant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vdcs', to='tenancy.tenant')), + ], + options={ + 'ordering': ['name'], + }, + ), + migrations.AddField( + model_name='interface', + name='vdcs', + field=models.ManyToManyField(related_name='interfaces', to='dcim.virtualdevicecontext'), + ), + migrations.AddConstraint( + model_name='virtualdevicecontext', + constraint=models.UniqueConstraint(fields=('device', 'identifier'), name='dcim_virtualdevicecontext_device_identifier'), + ), + migrations.AddConstraint( + model_name='virtualdevicecontext', + constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_virtualdevicecontext_device_name'), + ), + ] diff --git a/netbox/dcim/migrations/0167_module_status.py b/netbox/dcim/migrations/0167_module_status.py new file mode 100644 index 000000000..c048b4bd8 --- /dev/null +++ b/netbox/dcim/migrations/0167_module_status.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.2 on 2022-12-09 15:09 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0166_virtualdevicecontext'), + ] + + operations = [ + migrations.AddField( + model_name='module', + name='status', + field=models.CharField(default='active', max_length=50), + ), + ] diff --git a/netbox/dcim/migrations/0168_interface_template_enabled.py b/netbox/dcim/migrations/0168_interface_template_enabled.py new file mode 100644 index 000000000..af18be51d --- /dev/null +++ b/netbox/dcim/migrations/0168_interface_template_enabled.py @@ -0,0 +1,22 @@ +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0167_module_status'), + ] + + operations = [ + migrations.AddField( + model_name='interfacetemplate', + name='enabled', + field=models.BooleanField(default=True), + ), + migrations.AddField( + model_name='interfacetemplate', + name='bridge', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='bridge_interfaces', to='dcim.interfacetemplate'), + ), + ] diff --git a/netbox/dcim/migrations/0169_devicetype_default_platform.py b/netbox/dcim/migrations/0169_devicetype_default_platform.py new file mode 100644 index 000000000..a143f2c62 --- /dev/null +++ b/netbox/dcim/migrations/0169_devicetype_default_platform.py @@ -0,0 +1,19 @@ +# Generated by Django 4.1.6 on 2023-02-10 18:06 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0168_interface_template_enabled'), + ] + + operations = [ + migrations.AddField( + model_name='devicetype', + name='default_platform', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.platform'), + ), + ] diff --git a/netbox/dcim/migrations/0170_configtemplate.py b/netbox/dcim/migrations/0170_configtemplate.py new file mode 100644 index 000000000..f9508424d --- /dev/null +++ b/netbox/dcim/migrations/0170_configtemplate.py @@ -0,0 +1,28 @@ +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0086_configtemplate'), + ('dcim', '0169_devicetype_default_platform'), + ] + + operations = [ + migrations.AddField( + model_name='device', + name='config_template', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='%(class)ss', to='extras.configtemplate'), + ), + migrations.AddField( + model_name='devicerole', + name='config_template', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='device_roles', to='extras.configtemplate'), + ), + migrations.AddField( + model_name='platform', + name='config_template', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='platforms', to='extras.configtemplate'), + ), + ] diff --git a/netbox/dcim/migrations/0171_cabletermination_change_logging.py b/netbox/dcim/migrations/0171_cabletermination_change_logging.py new file mode 100644 index 000000000..e2131e45d --- /dev/null +++ b/netbox/dcim/migrations/0171_cabletermination_change_logging.py @@ -0,0 +1,21 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0170_configtemplate'), + ] + + operations = [ + migrations.AddField( + model_name='cabletermination', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AddField( + model_name='cabletermination', + name='last_updated', + field=models.DateTimeField(auto_now=True, null=True), + ), + ] diff --git a/netbox/dcim/migrations/0172_larger_power_draw_values.py b/netbox/dcim/migrations/0172_larger_power_draw_values.py new file mode 100644 index 000000000..729daf836 --- /dev/null +++ b/netbox/dcim/migrations/0172_larger_power_draw_values.py @@ -0,0 +1,42 @@ +# Generated by Django 4.1.9 on 2023-05-12 18:46 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0171_cabletermination_change_logging'), + ] + + operations = [ + migrations.AlterField( + model_name='powerport', + name='allocated_draw', + field=models.PositiveIntegerField( + blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)] + ), + ), + migrations.AlterField( + model_name='powerport', + name='maximum_draw', + field=models.PositiveIntegerField( + blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)] + ), + ), + migrations.AlterField( + model_name='powerporttemplate', + name='allocated_draw', + field=models.PositiveIntegerField( + blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)] + ), + ), + migrations.AlterField( + model_name='powerporttemplate', + name='maximum_draw', + field=models.PositiveIntegerField( + blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)] + ), + ), + ] diff --git a/netbox/dcim/migrations/0173_remove_napalm_fields.py b/netbox/dcim/migrations/0173_remove_napalm_fields.py new file mode 100644 index 000000000..61c7c5695 --- /dev/null +++ b/netbox/dcim/migrations/0173_remove_napalm_fields.py @@ -0,0 +1,19 @@ +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0172_larger_power_draw_values'), + ] + + operations = [ + migrations.RemoveField( + model_name='platform', + name='napalm_args', + ), + migrations.RemoveField( + model_name='platform', + name='napalm_driver', + ), + ] diff --git a/netbox/dcim/migrations/0174_device_latitude_device_longitude.py b/netbox/dcim/migrations/0174_device_latitude_device_longitude.py new file mode 100644 index 000000000..f9f72f9f8 --- /dev/null +++ b/netbox/dcim/migrations/0174_device_latitude_device_longitude.py @@ -0,0 +1,22 @@ +# Generated by Django 4.1.9 on 2023-05-31 22:13 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ('dcim', '0173_remove_napalm_fields'), + ] + + operations = [ + migrations.AddField( + model_name='device', + name='latitude', + field=models.DecimalField(blank=True, decimal_places=6, max_digits=8, null=True), + ), + migrations.AddField( + model_name='device', + name='longitude', + field=models.DecimalField(blank=True, decimal_places=6, max_digits=9, null=True), + ), + ] diff --git a/netbox/dcim/migrations/0174_rack_starting_unit.py b/netbox/dcim/migrations/0174_rack_starting_unit.py new file mode 100644 index 000000000..2d2b5f826 --- /dev/null +++ b/netbox/dcim/migrations/0174_rack_starting_unit.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.9 on 2023-05-31 15:47 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ('dcim', '0174_device_latitude_device_longitude'), + ] + + operations = [ + migrations.AddField( + model_name='rack', + name='starting_unit', + field=models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1)]), + ), + ] diff --git a/netbox/dcim/migrations/0175_device_oob_ip.py b/netbox/dcim/migrations/0175_device_oob_ip.py new file mode 100644 index 000000000..bf6a88ba8 --- /dev/null +++ b/netbox/dcim/migrations/0175_device_oob_ip.py @@ -0,0 +1,25 @@ +# Generated by Django 4.1.9 on 2023-07-24 20:29 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ('ipam', '0066_iprange_mark_utilized'), + ('dcim', '0174_rack_starting_unit'), + ] + + operations = [ + migrations.AddField( + model_name='device', + name='oob_ip', + field=models.OneToOneField( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name='+', + to='ipam.ipaddress', + ), + ), + ] diff --git a/netbox/dcim/migrations/0176_device_component_counters.py b/netbox/dcim/migrations/0176_device_component_counters.py new file mode 100644 index 000000000..60857ecb9 --- /dev/null +++ b/netbox/dcim/migrations/0176_device_component_counters.py @@ -0,0 +1,83 @@ +from django.db import migrations +from django.db.models import Count + +import utilities.fields +from utilities.counters import update_counts + + +def recalculate_device_counts(apps, schema_editor): + Device = apps.get_model("dcim", "Device") + + update_counts(Device, 'console_port_count', 'consoleports') + update_counts(Device, 'console_server_port_count', 'consoleserverports') + update_counts(Device, 'power_port_count', 'powerports') + update_counts(Device, 'power_outlet_count', 'poweroutlets') + update_counts(Device, 'interface_count', 'interfaces') + update_counts(Device, 'front_port_count', 'frontports') + update_counts(Device, 'rear_port_count', 'rearports') + update_counts(Device, 'device_bay_count', 'devicebays') + update_counts(Device, 'module_bay_count', 'modulebays') + update_counts(Device, 'inventory_item_count', 'inventoryitems') + + +class Migration(migrations.Migration): + dependencies = [ + ('dcim', '0175_device_oob_ip'), + ] + + operations = [ + migrations.AddField( + model_name='device', + name='console_port_count', + field=utilities.fields.CounterCacheField(default=0, to_field='device', to_model='dcim.ConsolePort'), + ), + migrations.AddField( + model_name='device', + name='console_server_port_count', + field=utilities.fields.CounterCacheField(default=0, to_field='device', to_model='dcim.ConsoleServerPort'), + ), + migrations.AddField( + model_name='device', + name='power_port_count', + field=utilities.fields.CounterCacheField(default=0, to_field='device', to_model='dcim.PowerPort'), + ), + migrations.AddField( + model_name='device', + name='power_outlet_count', + field=utilities.fields.CounterCacheField(default=0, to_field='device', to_model='dcim.PowerOutlet'), + ), + migrations.AddField( + model_name='device', + name='interface_count', + field=utilities.fields.CounterCacheField(default=0, to_field='device', to_model='dcim.Interface'), + ), + migrations.AddField( + model_name='device', + name='front_port_count', + field=utilities.fields.CounterCacheField(default=0, to_field='device', to_model='dcim.FrontPort'), + ), + migrations.AddField( + model_name='device', + name='rear_port_count', + field=utilities.fields.CounterCacheField(default=0, to_field='device', to_model='dcim.RearPort'), + ), + migrations.AddField( + model_name='device', + name='device_bay_count', + field=utilities.fields.CounterCacheField(default=0, to_field='device', to_model='dcim.DeviceBay'), + ), + migrations.AddField( + model_name='device', + name='module_bay_count', + field=utilities.fields.CounterCacheField(default=0, to_field='device', to_model='dcim.ModuleBay'), + ), + migrations.AddField( + model_name='device', + name='inventory_item_count', + field=utilities.fields.CounterCacheField(default=0, to_field='device', to_model='dcim.InventoryItem'), + ), + migrations.RunPython( + recalculate_device_counts, + reverse_code=migrations.RunPython.noop + ), + ] diff --git a/netbox/dcim/migrations/0177_devicetype_component_counters.py b/netbox/dcim/migrations/0177_devicetype_component_counters.py new file mode 100644 index 000000000..b452ce2d9 --- /dev/null +++ b/netbox/dcim/migrations/0177_devicetype_component_counters.py @@ -0,0 +1,83 @@ +from django.db import migrations +from django.db.models import Count + +import utilities.fields +from utilities.counters import update_counts + + +def recalculate_devicetype_template_counts(apps, schema_editor): + DeviceType = apps.get_model("dcim", "DeviceType") + + update_counts(DeviceType, 'console_port_template_count', 'consoleporttemplates') + update_counts(DeviceType, 'console_server_port_template_count', 'consoleserverporttemplates') + update_counts(DeviceType, 'power_port_template_count', 'powerporttemplates') + update_counts(DeviceType, 'power_outlet_template_count', 'poweroutlettemplates') + update_counts(DeviceType, 'interface_template_count', 'interfacetemplates') + update_counts(DeviceType, 'front_port_template_count', 'frontporttemplates') + update_counts(DeviceType, 'rear_port_template_count', 'rearporttemplates') + update_counts(DeviceType, 'device_bay_template_count', 'devicebaytemplates') + update_counts(DeviceType, 'module_bay_template_count', 'modulebaytemplates') + update_counts(DeviceType, 'inventory_item_template_count', 'inventoryitemtemplates') + + +class Migration(migrations.Migration): + dependencies = [ + ('dcim', '0176_device_component_counters'), + ] + + operations = [ + migrations.AddField( + model_name='devicetype', + name='console_port_template_count', + field=utilities.fields.CounterCacheField(default=0, to_field='device_type', to_model='dcim.ConsolePortTemplate'), + ), + migrations.AddField( + model_name='devicetype', + name='console_server_port_template_count', + field=utilities.fields.CounterCacheField(default=0, to_field='device_type', to_model='dcim.ConsoleServerPortTemplate'), + ), + migrations.AddField( + model_name='devicetype', + name='power_port_template_count', + field=utilities.fields.CounterCacheField(default=0, to_field='device_type', to_model='dcim.PowerPortTemplate'), + ), + migrations.AddField( + model_name='devicetype', + name='power_outlet_template_count', + field=utilities.fields.CounterCacheField(default=0, to_field='device_type', to_model='dcim.PowerOutletTemplate'), + ), + migrations.AddField( + model_name='devicetype', + name='interface_template_count', + field=utilities.fields.CounterCacheField(default=0, to_field='device_type', to_model='dcim.InterfaceTemplate'), + ), + migrations.AddField( + model_name='devicetype', + name='front_port_template_count', + field=utilities.fields.CounterCacheField(default=0, to_field='device_type', to_model='dcim.FrontPortTemplate'), + ), + migrations.AddField( + model_name='devicetype', + name='rear_port_template_count', + field=utilities.fields.CounterCacheField(default=0, to_field='device_type', to_model='dcim.RearPortTemplate'), + ), + migrations.AddField( + model_name='devicetype', + name='device_bay_template_count', + field=utilities.fields.CounterCacheField(default=0, to_field='device_type', to_model='dcim.DeviceBayTemplate'), + ), + migrations.AddField( + model_name='devicetype', + name='module_bay_template_count', + field=utilities.fields.CounterCacheField(default=0, to_field='device_type', to_model='dcim.ModuleBayTemplate'), + ), + migrations.AddField( + model_name='devicetype', + name='inventory_item_template_count', + field=utilities.fields.CounterCacheField(default=0, to_field='device_type', to_model='dcim.InventoryItemTemplate'), + ), + migrations.RunPython( + recalculate_devicetype_template_counts, + reverse_code=migrations.RunPython.noop + ), + ] diff --git a/netbox/dcim/migrations/0178_virtual_chassis_member_counter.py b/netbox/dcim/migrations/0178_virtual_chassis_member_counter.py new file mode 100644 index 000000000..99b304b66 --- /dev/null +++ b/netbox/dcim/migrations/0178_virtual_chassis_member_counter.py @@ -0,0 +1,31 @@ +from django.db import migrations +from django.db.models import Count + +import utilities.fields +from utilities.counters import update_counts + + +def populate_virtualchassis_members(apps, schema_editor): + VirtualChassis = apps.get_model('dcim', 'VirtualChassis') + + update_counts(VirtualChassis, 'member_count', 'members') + + +class Migration(migrations.Migration): + dependencies = [ + ('dcim', '0177_devicetype_component_counters'), + ] + + operations = [ + migrations.AddField( + model_name='virtualchassis', + name='member_count', + field=utilities.fields.CounterCacheField( + default=0, to_field='virtual_chassis', to_model='dcim.Device' + ), + ), + migrations.RunPython( + code=populate_virtualchassis_members, + reverse_code=migrations.RunPython.noop + ), + ] diff --git a/netbox/dcim/migrations/0179_interfacetemplate_rf_role.py b/netbox/dcim/migrations/0179_interfacetemplate_rf_role.py new file mode 100644 index 000000000..44eb08853 --- /dev/null +++ b/netbox/dcim/migrations/0179_interfacetemplate_rf_role.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.2 on 2023-07-18 07:55 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0178_virtual_chassis_member_counter'), + ] + + operations = [ + migrations.AddField( + model_name='interfacetemplate', + name='rf_role', + field=models.CharField(blank=True, max_length=30), + ), + ] diff --git a/netbox/dcim/migrations/0180_powerfeed_tenant.py b/netbox/dcim/migrations/0180_powerfeed_tenant.py new file mode 100644 index 000000000..af550b21d --- /dev/null +++ b/netbox/dcim/migrations/0180_powerfeed_tenant.py @@ -0,0 +1,20 @@ +# Generated by Django 4.1.8 on 2023-07-29 11:29 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('tenancy', '0010_tenant_relax_uniqueness'), + ('dcim', '0179_interfacetemplate_rf_role'), + ] + + operations = [ + migrations.AddField( + model_name='powerfeed', + name='tenant', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='power_feeds', to='tenancy.tenant'), + ), + ] diff --git a/netbox/dcim/migrations/0181_rename_device_role_device_role.py b/netbox/dcim/migrations/0181_rename_device_role_device_role.py new file mode 100644 index 000000000..e32e00221 --- /dev/null +++ b/netbox/dcim/migrations/0181_rename_device_role_device_role.py @@ -0,0 +1,35 @@ +from django.db import migrations + + +def update_table_configs(apps, schema_editor): + """ + Replace the `device_role` column in DeviceTable configs with `role`. + """ + UserConfig = apps.get_model('users', 'UserConfig') + + for table in ('DeviceTable', 'DeviceBayTable'): + for config in UserConfig.objects.filter(**{f'data__tables__{table}__columns__contains': 'device_role'}): + config.data['tables'][table]['columns'] = [ + 'role' if x == 'device_role' else x + for x in config.data['tables'][table]['columns'] + ] + config.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0180_powerfeed_tenant'), + ] + + operations = [ + migrations.RenameField( + model_name='device', + old_name='device_role', + new_name='role', + ), + migrations.RunPython( + code=update_table_configs, + reverse_code=migrations.RunPython.noop + ), + ] diff --git a/netbox/dcim/migrations/0182_zero_length_cable_fix.py b/netbox/dcim/migrations/0182_zero_length_cable_fix.py new file mode 100644 index 000000000..080e00717 --- /dev/null +++ b/netbox/dcim/migrations/0182_zero_length_cable_fix.py @@ -0,0 +1,22 @@ +from django.db import migrations + + +def update_cable_lengths(apps, schema_editor): + Cable = apps.get_model('dcim', 'Cable') + + # Set the absolute length for any zero-length Cables + Cable.objects.filter(length=0).update(_abs_length=0) + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0181_rename_device_role_device_role'), + ] + + operations = [ + migrations.RunPython( + code=update_cable_lengths, + reverse_code=migrations.RunPython.noop + ), + ] diff --git a/netbox/extras/migrations/0001_initial.py b/netbox/extras/migrations/0001_initial.py deleted file mode 100644 index 4c538d213..000000000 --- a/netbox/extras/migrations/0001_initial.py +++ /dev/null @@ -1,453 +0,0 @@ -from django.conf import settings -import django.contrib.postgres.fields -import django.core.validators -from django.db import migrations, models -import django.db.models.deletion -import extras.fields -import extras.models.customfields -import extras.models.mixins -import extras.utils -import re -import taggit.managers -import utilities.fields -import utilities.json -import utilities.validators -import uuid - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ('core', '0001_initial'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('contenttypes', '0002_remove_content_type_name'), - ] - - operations = [ - migrations.CreateModel( - name='Report', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ], - options={ - 'managed': False, - }, - ), - migrations.CreateModel( - name='Script', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ], - options={ - 'managed': False, - }, - ), - migrations.CreateModel( - name='Bookmark', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True)), - ('object_id', models.PositiveBigIntegerField()), - ], - options={ - 'verbose_name': 'bookmark', - 'verbose_name_plural': 'bookmarks', - 'ordering': ('created', 'pk'), - }, - ), - migrations.CreateModel( - name='Branch', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('name', models.CharField(max_length=100, unique=True)), - ('description', models.CharField(blank=True, max_length=200)), - ], - options={ - 'verbose_name': 'branch', - 'verbose_name_plural': 'branches', - 'ordering': ('name',), - }, - ), - migrations.CreateModel( - name='CachedValue', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('timestamp', models.DateTimeField(auto_now_add=True)), - ('object_id', models.PositiveBigIntegerField()), - ('field', models.CharField(max_length=200)), - ('type', models.CharField(max_length=30)), - ('value', extras.fields.CachedValueField()), - ('weight', models.PositiveSmallIntegerField(default=1000)), - ], - options={ - 'verbose_name': 'cached value', - 'verbose_name_plural': 'cached values', - 'ordering': ('weight', 'object_type', 'object_id'), - }, - ), - migrations.CreateModel( - name='ConfigContext', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('data_path', models.CharField(blank=True, editable=False, max_length=1000)), - ('auto_sync_enabled', models.BooleanField(default=False)), - ('data_synced', models.DateTimeField(blank=True, editable=False, null=True)), - ('name', models.CharField(max_length=100, unique=True)), - ('weight', models.PositiveSmallIntegerField(default=1000)), - ('description', models.CharField(blank=True, max_length=200)), - ('is_active', models.BooleanField(default=True)), - ('data', models.JSONField()), - ], - options={ - 'verbose_name': 'config context', - 'verbose_name_plural': 'config contexts', - 'ordering': ['weight', 'name'], - }, - ), - migrations.CreateModel( - name='ConfigRevision', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True)), - ('comment', models.CharField(blank=True, max_length=200)), - ('data', models.JSONField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'config revision', - 'verbose_name_plural': 'config revisions', - 'ordering': ['-created'], - }, - ), - migrations.CreateModel( - name='CustomFieldChoiceSet', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('name', models.CharField(max_length=100, unique=True)), - ('description', models.CharField(blank=True, max_length=200)), - ('base_choices', models.CharField(blank=True, max_length=50)), - ('extra_choices', django.contrib.postgres.fields.ArrayField(base_field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=100), size=2), blank=True, null=True, size=None)), - ('order_alphabetically', models.BooleanField(default=False)), - ], - options={ - 'verbose_name': 'custom field choice set', - 'verbose_name_plural': 'custom field choice sets', - 'ordering': ('name',), - }, - ), - migrations.CreateModel( - name='Tag', - fields=[ - ('name', models.CharField(max_length=100, unique=True)), - ('slug', models.SlugField(allow_unicode=True, max_length=100, unique=True)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('id', models.BigAutoField(primary_key=True, serialize=False)), - ('color', utilities.fields.ColorField(default='9e9e9e', max_length=6)), - ('description', models.CharField(blank=True, max_length=200)), - ('object_types', models.ManyToManyField(blank=True, related_name='+', to='contenttypes.contenttype')), - ], - options={ - 'verbose_name': 'tag', - 'verbose_name_plural': 'tags', - 'ordering': ['name'], - }, - ), - migrations.CreateModel( - name='TaggedItem', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('object_id', models.IntegerField(db_index=True)), - ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(app_label)s_%(class)s_tagged_items', to='contenttypes.contenttype')), - ('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(app_label)s_%(class)s_items', to='extras.tag')), - ], - options={ - 'verbose_name': 'tagged item', - 'verbose_name_plural': 'tagged items', - }, - ), - migrations.CreateModel( - name='ReportModule', - fields=[ - ], - options={ - 'verbose_name': 'report module', - 'verbose_name_plural': 'report modules', - 'proxy': True, - 'indexes': [], - 'constraints': [], - }, - bases=(extras.models.mixins.PythonModuleMixin, 'core.managedfile', models.Model), - ), - migrations.CreateModel( - name='ScriptModule', - fields=[ - ], - options={ - 'verbose_name': 'script module', - 'verbose_name_plural': 'script modules', - 'proxy': True, - 'indexes': [], - 'constraints': [], - }, - bases=(extras.models.mixins.PythonModuleMixin, 'core.managedfile', models.Model), - ), - migrations.CreateModel( - name='Webhook', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=150, unique=True)), - ('type_create', models.BooleanField(default=False)), - ('type_update', models.BooleanField(default=False)), - ('type_delete', models.BooleanField(default=False)), - ('type_job_start', models.BooleanField(default=False)), - ('type_job_end', models.BooleanField(default=False)), - ('payload_url', models.CharField(max_length=500)), - ('enabled', models.BooleanField(default=True)), - ('http_method', models.CharField(default='POST', max_length=30)), - ('http_content_type', models.CharField(default='application/json', max_length=100)), - ('additional_headers', models.TextField(blank=True)), - ('body_template', models.TextField(blank=True)), - ('secret', models.CharField(blank=True, max_length=255)), - ('conditions', models.JSONField(blank=True, null=True)), - ('ssl_verification', models.BooleanField(default=True)), - ('ca_file_path', models.CharField(blank=True, max_length=4096, null=True)), - ('content_types', models.ManyToManyField(related_name='webhooks', to='contenttypes.contenttype')), - ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), - ], - options={ - 'verbose_name': 'webhook', - 'verbose_name_plural': 'webhooks', - 'ordering': ('name',), - }, - ), - migrations.CreateModel( - name='StagedChange', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('action', models.CharField(max_length=20)), - ('object_id', models.PositiveBigIntegerField(blank=True, null=True)), - ('data', models.JSONField(blank=True, null=True)), - ('branch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='staged_changes', to='extras.branch')), - ('object_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='contenttypes.contenttype')), - ], - options={ - 'verbose_name': 'staged change', - 'verbose_name_plural': 'staged changes', - 'ordering': ('pk',), - }, - ), - migrations.CreateModel( - name='SavedFilter', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('name', models.CharField(max_length=100, unique=True)), - ('slug', models.SlugField(max_length=100, unique=True)), - ('description', models.CharField(blank=True, max_length=200)), - ('weight', models.PositiveSmallIntegerField(default=100)), - ('enabled', models.BooleanField(default=True)), - ('shared', models.BooleanField(default=True)), - ('parameters', models.JSONField()), - ('content_types', models.ManyToManyField(related_name='saved_filters', to='contenttypes.contenttype')), - ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), - ], - options={ - 'verbose_name': 'saved filter', - 'verbose_name_plural': 'saved filters', - 'ordering': ('weight', 'name'), - }, - ), - migrations.CreateModel( - name='ObjectChange', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('time', models.DateTimeField(auto_now_add=True, db_index=True)), - ('user_name', models.CharField(editable=False, max_length=150)), - ('request_id', models.UUIDField(db_index=True, editable=False)), - ('action', models.CharField(max_length=50)), - ('changed_object_id', models.PositiveBigIntegerField()), - ('related_object_id', models.PositiveBigIntegerField(blank=True, null=True)), - ('object_repr', models.CharField(editable=False, max_length=200)), - ('prechange_data', models.JSONField(blank=True, editable=False, null=True)), - ('postchange_data', models.JSONField(blank=True, editable=False, null=True)), - ('changed_object_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype')), - ('related_object_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype')), - ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='changes', to=settings.AUTH_USER_MODEL)), - ], - options={ - 'verbose_name': 'object change', - 'verbose_name_plural': 'object changes', - 'ordering': ['-time'], - }, - ), - migrations.CreateModel( - name='JournalEntry', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('assigned_object_id', models.PositiveBigIntegerField()), - ('kind', models.CharField(default='info', max_length=30)), - ('comments', models.TextField()), - ('assigned_object_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')), - ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), - ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), - ], - options={ - 'verbose_name': 'journal entry', - 'verbose_name_plural': 'journal entries', - 'ordering': ('-created',), - }, - ), - migrations.CreateModel( - name='ImageAttachment', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('object_id', models.PositiveBigIntegerField()), - ('image', models.ImageField(height_field='image_height', upload_to=extras.utils.image_upload, width_field='image_width')), - ('image_height', models.PositiveSmallIntegerField()), - ('image_width', models.PositiveSmallIntegerField()), - ('name', models.CharField(blank=True, max_length=50)), - ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')), - ], - options={ - 'verbose_name': 'image attachment', - 'verbose_name_plural': 'image attachments', - 'ordering': ('name', 'pk'), - }, - ), - migrations.CreateModel( - name='ExportTemplate', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('data_path', models.CharField(blank=True, editable=False, max_length=1000)), - ('auto_sync_enabled', models.BooleanField(default=False)), - ('data_synced', models.DateTimeField(blank=True, editable=False, null=True)), - ('name', models.CharField(max_length=100)), - ('description', models.CharField(blank=True, max_length=200)), - ('template_code', models.TextField()), - ('mime_type', models.CharField(blank=True, max_length=50)), - ('file_extension', models.CharField(blank=True, max_length=15)), - ('as_attachment', models.BooleanField(default=True)), - ('content_types', models.ManyToManyField(related_name='export_templates', to='contenttypes.contenttype')), - ('data_file', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='core.datafile')), - ('data_source', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='core.datasource')), - ], - options={ - 'verbose_name': 'export template', - 'verbose_name_plural': 'export templates', - 'ordering': ('name',), - }, - ), - migrations.CreateModel( - name='Dashboard', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('layout', models.JSONField(default=list)), - ('config', models.JSONField(default=dict)), - ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='dashboard', to=settings.AUTH_USER_MODEL)), - ], - options={ - 'verbose_name': 'dashboard', - 'verbose_name_plural': 'dashboards', - }, - ), - migrations.CreateModel( - name='CustomLink', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('name', models.CharField(max_length=100, unique=True)), - ('enabled', models.BooleanField(default=True)), - ('link_text', models.TextField()), - ('link_url', models.TextField()), - ('weight', models.PositiveSmallIntegerField(default=100)), - ('group_name', models.CharField(blank=True, max_length=50)), - ('button_class', models.CharField(default='outline-dark', max_length=30)), - ('new_window', models.BooleanField(default=False)), - ('content_types', models.ManyToManyField(related_name='custom_links', to='contenttypes.contenttype')), - ], - options={ - 'verbose_name': 'custom link', - 'verbose_name_plural': 'custom links', - 'ordering': ['group_name', 'weight', 'name'], - }, - ), - migrations.CreateModel( - name='CustomField', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('type', models.CharField(default='text', max_length=50)), - ('name', models.CharField(max_length=50, unique=True, validators=[django.core.validators.RegexValidator(flags=re.RegexFlag['IGNORECASE'], message='Only alphanumeric characters and underscores are allowed.', regex='^[a-z0-9_]+$'), django.core.validators.RegexValidator(flags=re.RegexFlag['IGNORECASE'], inverse_match=True, message='Double underscores are not permitted in custom field names.', regex='__')])), - ('label', models.CharField(blank=True, max_length=50)), - ('group_name', models.CharField(blank=True, max_length=50)), - ('description', models.CharField(blank=True, max_length=200)), - ('required', models.BooleanField(default=False)), - ('search_weight', models.PositiveSmallIntegerField(default=1000)), - ('filter_logic', models.CharField(default='loose', max_length=50)), - ('default', models.JSONField(blank=True, null=True)), - ('weight', models.PositiveSmallIntegerField(default=100)), - ('validation_minimum', models.IntegerField(blank=True, null=True)), - ('validation_maximum', models.IntegerField(blank=True, null=True)), - ('validation_regex', models.CharField(blank=True, max_length=500, validators=[utilities.validators.validate_regex])), - ('ui_visibility', models.CharField(default='read-write', max_length=50)), - ('is_cloneable', models.BooleanField(default=False)), - ('choice_set', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='choices_for', to='extras.customfieldchoiceset')), - ('content_types', models.ManyToManyField(related_name='custom_fields', to='contenttypes.contenttype')), - ('object_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='contenttypes.contenttype')), - ], - options={ - 'verbose_name': 'custom field', - 'verbose_name_plural': 'custom fields', - 'ordering': ['group_name', 'weight', 'name'], - }, - managers=[ - ('objects', extras.models.customfields.CustomFieldManager()), - ], - ), - migrations.CreateModel( - name='ConfigTemplate', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('data_path', models.CharField(blank=True, editable=False, max_length=1000)), - ('auto_sync_enabled', models.BooleanField(default=False)), - ('data_synced', models.DateTimeField(blank=True, editable=False, null=True)), - ('name', models.CharField(max_length=100)), - ('description', models.CharField(blank=True, max_length=200)), - ('template_code', models.TextField()), - ('environment_params', models.JSONField(blank=True, default=dict, null=True)), - ('data_file', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='core.datafile')), - ('data_source', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='core.datasource')), - ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), - ], - options={ - 'verbose_name': 'config template', - 'verbose_name_plural': 'config templates', - 'ordering': ('name',), - }, - ), - ] diff --git a/netbox/extras/migrations/0001_squashed.py b/netbox/extras/migrations/0001_squashed.py new file mode 100644 index 000000000..6f1f77e53 --- /dev/null +++ b/netbox/extras/migrations/0001_squashed.py @@ -0,0 +1,235 @@ +from django.conf import settings +import django.contrib.postgres.fields +from django.db import migrations, models +import django.db.models.deletion +import extras.models.customfields +import extras.utils +import utilities.fields +import utilities.validators + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('contenttypes', '0002_remove_content_type_name'), + ] + + replaces = [ + ('extras', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Report', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)), + ], + options={ + 'managed': False, + }, + ), + migrations.CreateModel( + name='Script', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)), + ], + options={ + 'managed': False, + }, + ), + migrations.CreateModel( + name='ConfigContext', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, unique=True)), + ('weight', models.PositiveSmallIntegerField(default=1000)), + ('description', models.CharField(blank=True, max_length=200)), + ('is_active', models.BooleanField(default=True)), + ('data', models.JSONField()), + ], + options={ + 'ordering': ['weight', 'name'], + }, + ), + migrations.CreateModel( + name='Tag', + fields=[ + ('name', models.CharField(max_length=100, unique=True)), + ('slug', models.SlugField(max_length=100, unique=True)), + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('color', utilities.fields.ColorField(default='9e9e9e', max_length=6)), + ('description', models.CharField(blank=True, max_length=200)), + ], + options={ + 'ordering': ['name'], + }, + ), + migrations.CreateModel( + name='Webhook', + fields=[ + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=150, unique=True)), + ('type_create', models.BooleanField(default=False)), + ('type_update', models.BooleanField(default=False)), + ('type_delete', models.BooleanField(default=False)), + ('payload_url', models.CharField(max_length=500)), + ('enabled', models.BooleanField(default=True)), + ('http_method', models.CharField(default='POST', max_length=30)), + ('http_content_type', models.CharField(default='application/json', max_length=100)), + ('additional_headers', models.TextField(blank=True)), + ('body_template', models.TextField(blank=True)), + ('secret', models.CharField(blank=True, max_length=255)), + ('ssl_verification', models.BooleanField(default=True)), + ('ca_file_path', models.CharField(blank=True, max_length=4096, null=True)), + ('content_types', models.ManyToManyField(related_name='webhooks', to='contenttypes.ContentType')), + ], + options={ + 'ordering': ('name',), + }, + ), + migrations.CreateModel( + name='TaggedItem', + fields=[ + ('object_id', models.IntegerField(db_index=True)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(app_label)s_%(class)s_tagged_items', to='contenttypes.contenttype')), + ('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(app_label)s_%(class)s_items', to='extras.tag')), + ], + ), + migrations.CreateModel( + name='ObjectChange', + fields=[ + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('time', models.DateTimeField(auto_now_add=True, db_index=True)), + ('user_name', models.CharField(editable=False, max_length=150)), + ('request_id', models.UUIDField(editable=False)), + ('action', models.CharField(max_length=50)), + ('changed_object_id', models.PositiveIntegerField()), + ('related_object_id', models.PositiveIntegerField(blank=True, null=True)), + ('object_repr', models.CharField(editable=False, max_length=200)), + ('prechange_data', models.JSONField(blank=True, editable=False, null=True)), + ('postchange_data', models.JSONField(blank=True, editable=False, null=True)), + ('changed_object_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype')), + ('related_object_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype')), + ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='changes', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'ordering': ['-time'], + }, + ), + migrations.CreateModel( + name='JournalEntry', + fields=[ + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('assigned_object_id', models.PositiveIntegerField()), + ('created', models.DateTimeField(auto_now_add=True)), + ('kind', models.CharField(default='info', max_length=30)), + ('comments', models.TextField()), + ('assigned_object_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')), + ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name_plural': 'journal entries', + 'ordering': ('-created',), + }, + ), + migrations.CreateModel( + name='JobResult', + fields=[ + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=255)), + ('created', models.DateTimeField(auto_now_add=True)), + ('completed', models.DateTimeField(blank=True, null=True)), + ('status', models.CharField(default='pending', max_length=30)), + ('data', models.JSONField(blank=True, null=True)), + ('job_id', models.UUIDField(unique=True)), + ('obj_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='job_results', to='contenttypes.contenttype')), + ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'ordering': ['obj_type', 'name', '-created'], + }, + ), + migrations.CreateModel( + name='ImageAttachment', + fields=[ + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('object_id', models.PositiveIntegerField()), + ('image', models.ImageField(height_field='image_height', upload_to=extras.utils.image_upload, width_field='image_width')), + ('image_height', models.PositiveSmallIntegerField()), + ('image_width', models.PositiveSmallIntegerField()), + ('name', models.CharField(blank=True, max_length=50)), + ('created', models.DateTimeField(auto_now_add=True)), + ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')), + ], + options={ + 'ordering': ('name', 'pk'), + }, + ), + migrations.CreateModel( + name='ExportTemplate', + fields=[ + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100)), + ('description', models.CharField(blank=True, max_length=200)), + ('template_code', models.TextField()), + ('mime_type', models.CharField(blank=True, max_length=50)), + ('file_extension', models.CharField(blank=True, max_length=15)), + ('as_attachment', models.BooleanField(default=True)), + ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')), + ], + options={ + 'ordering': ['content_type', 'name'], + }, + ), + migrations.CreateModel( + name='CustomLink', + fields=[ + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, unique=True)), + ('link_text', models.CharField(max_length=500)), + ('link_url', models.CharField(max_length=500)), + ('weight', models.PositiveSmallIntegerField(default=100)), + ('group_name', models.CharField(blank=True, max_length=50)), + ('button_class', models.CharField(default='default', max_length=30)), + ('new_window', models.BooleanField(default=False)), + ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')), + ], + options={ + 'ordering': ['group_name', 'weight', 'name'], + }, + ), + migrations.CreateModel( + name='CustomField', + fields=[ + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('type', models.CharField(default='text', max_length=50)), + ('name', models.CharField(max_length=50, unique=True)), + ('label', models.CharField(blank=True, max_length=50)), + ('description', models.CharField(blank=True, max_length=200)), + ('required', models.BooleanField(default=False)), + ('filter_logic', models.CharField(default='loose', max_length=50)), + ('default', models.JSONField(blank=True, null=True)), + ('weight', models.PositiveSmallIntegerField(default=100)), + ('validation_minimum', models.PositiveIntegerField(blank=True, null=True)), + ('validation_maximum', models.PositiveIntegerField(blank=True, null=True)), + ('validation_regex', models.CharField(blank=True, max_length=500, validators=[utilities.validators.validate_regex])), + ('choices', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=100), blank=True, null=True, size=None)), + ('content_types', models.ManyToManyField(related_name='custom_fields', to='contenttypes.ContentType')), + ], + options={ + 'ordering': ['weight', 'name'], + }, + managers=[ + ('objects', extras.models.customfields.CustomFieldManager()), + ], + ), + ] diff --git a/netbox/extras/migrations/0002_squashed.py b/netbox/extras/migrations/0002_squashed.py deleted file mode 100644 index 6475272e7..000000000 --- a/netbox/extras/migrations/0002_squashed.py +++ /dev/null @@ -1,228 +0,0 @@ -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ('core', '0002_squashed'), - ('extras', '0001_initial'), - ('virtualization', '0001_initial'), - ('contenttypes', '0002_remove_content_type_name'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('dcim', '0003_squashed'), - ('tenancy', '0001_initial'), - ] - - replaces = [ - ('extras', '0002_custom_fields'), - ('extras', '0003_exporttemplate_add_description'), - ('extras', '0004_topologymap_change_comma_to_semicolon'), - ('extras', '0005_useraction_add_bulk_create'), - ('extras', '0006_add_imageattachments'), - ('extras', '0007_unicode_literals'), - ('extras', '0008_reports'), - ('extras', '0009_topologymap_type'), - ('extras', '0010_customfield_filter_logic'), - ('extras', '0011_django2'), - ('extras', '0012_webhooks'), - ('extras', '0013_objectchange'), - ('extras', '0014_configcontexts'), - ('extras', '0015_remove_useraction'), - ('extras', '0016_exporttemplate_add_cable'), - ('extras', '0017_exporttemplate_mime_type_length'), - ('extras', '0018_exporttemplate_add_jinja2'), - ('extras', '0019_tag_taggeditem'), - ('extras', '0020_tag_data'), - ('extras', '0021_add_color_comments_changelog_to_tag'), - ('extras', '0022_custom_links'), - ('extras', '0023_fix_tag_sequences'), - ('extras', '0024_scripts'), - ('extras', '0025_objectchange_time_index'), - ('extras', '0026_webhook_ca_file_path'), - ('extras', '0027_webhook_additional_headers'), - ('extras', '0028_remove_topology_maps'), - ('extras', '0029_3569_customfield_fields'), - ('extras', '0030_3569_objectchange_fields'), - ('extras', '0031_3569_exporttemplate_fields'), - ('extras', '0032_3569_webhook_fields'), - ('extras', '0033_graph_type_template_language'), - ('extras', '0034_configcontext_tags'), - ('extras', '0035_deterministic_ordering'), - ('extras', '0036_contenttype_filters_to_q_objects'), - ('extras', '0037_configcontexts_clusters'), - ('extras', '0038_webhook_template_support'), - ('extras', '0039_update_features_content_types'), - ('extras', '0040_standardize_description'), - ('extras', '0041_tag_description'), - ('extras', '0042_customfield_manager'), - ('extras', '0043_report'), - ('extras', '0044_jobresult'), - ('extras', '0045_configcontext_changelog'), - ('extras', '0046_update_jsonfield'), - ('extras', '0047_tag_ordering'), - ('extras', '0048_exporttemplate_remove_template_language'), - ('extras', '0049_remove_graph'), - ('extras', '0050_customfield_changes'), - ('extras', '0051_migrate_customfields'), - ('extras', '0052_customfield_cleanup'), - ('extras', '0053_rename_webhook_obj_type'), - ('extras', '0054_standardize_models'), - ('extras', '0055_objectchange_data'), - ('extras', '0056_extend_configcontext'), - ('extras', '0057_customlink_rename_fields'), - ('extras', '0058_journalentry'), - ('extras', '0059_exporttemplate_as_attachment'), - ('extras', '0060_customlink_button_class'), - ('extras', '0061_extras_change_logging'), - ('extras', '0062_clear_secrets_changelog'), - ('extras', '0063_webhook_conditions'), - ('extras', '0064_configrevision'), - ('extras', '0065_imageattachment_change_logging'), - ('extras', '0066_customfield_name_validation'), - ('extras', '0067_customfield_min_max_values'), - ('extras', '0068_configcontext_cluster_types'), - ('extras', '0069_custom_object_field'), - ('extras', '0070_customlink_enabled'), - ('extras', '0071_standardize_id_fields'), - ('extras', '0072_created_datetimefield'), - ('extras', '0073_journalentry_tags_custom_fields'), - ('extras', '0074_customfield_extensions'), - ('extras', '0075_configcontext_locations'), - ('extras', '0076_tag_slug_unicode'), - ('extras', '0077_customlink_extend_text_and_url'), - ('extras', '0078_unique_constraints'), - ('extras', '0079_scheduled_jobs'), - ('extras', '0080_customlink_content_types'), - ('extras', '0081_exporttemplate_content_types'), - ('extras', '0082_savedfilter'), - ('extras', '0083_search'), - ('extras', '0084_staging'), - ('extras', '0085_synced_data'), - ('extras', '0086_configtemplate'), - ('extras', '0087_dashboard'), - ('extras', '0088_jobresult_webhooks'), - ('extras', '0089_customfield_is_cloneable'), - ('extras', '0090_objectchange_index_request_id'), - ('extras', '0091_create_managedfiles'), - ('extras', '0092_delete_jobresult'), - ('extras', '0093_configrevision_ordering'), - ('extras', '0094_tag_object_types'), - ('extras', '0095_bookmarks'), - ('extras', '0096_customfieldchoiceset'), - ('extras', '0097_customfield_remove_choices'), - ('extras', '0098_webhook_custom_field_data_webhook_tags'), - ] - - operations = [ - migrations.AddField( - model_name='configcontext', - name='cluster_groups', - field=models.ManyToManyField(blank=True, related_name='+', to='virtualization.clustergroup'), - ), - migrations.AddField( - model_name='configcontext', - name='cluster_types', - field=models.ManyToManyField(blank=True, related_name='+', to='virtualization.clustertype'), - ), - migrations.AddField( - model_name='configcontext', - name='clusters', - field=models.ManyToManyField(blank=True, related_name='+', to='virtualization.cluster'), - ), - migrations.AddField( - model_name='configcontext', - name='data_file', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='core.datafile'), - ), - migrations.AddField( - model_name='configcontext', - name='data_source', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='core.datasource'), - ), - migrations.AddField( - model_name='configcontext', - name='device_types', - field=models.ManyToManyField(blank=True, related_name='+', to='dcim.devicetype'), - ), - migrations.AddField( - model_name='configcontext', - name='locations', - field=models.ManyToManyField(blank=True, related_name='+', to='dcim.location'), - ), - migrations.AddField( - model_name='configcontext', - name='platforms', - field=models.ManyToManyField(blank=True, related_name='+', to='dcim.platform'), - ), - migrations.AddField( - model_name='configcontext', - name='regions', - field=models.ManyToManyField(blank=True, related_name='+', to='dcim.region'), - ), - migrations.AddField( - model_name='configcontext', - name='roles', - field=models.ManyToManyField(blank=True, related_name='+', to='dcim.devicerole'), - ), - migrations.AddField( - model_name='configcontext', - name='site_groups', - field=models.ManyToManyField(blank=True, related_name='+', to='dcim.sitegroup'), - ), - migrations.AddField( - model_name='configcontext', - name='sites', - field=models.ManyToManyField(blank=True, related_name='+', to='dcim.site'), - ), - migrations.AddField( - model_name='configcontext', - name='tags', - field=models.ManyToManyField(blank=True, related_name='+', to='extras.tag'), - ), - migrations.AddField( - model_name='configcontext', - name='tenant_groups', - field=models.ManyToManyField(blank=True, related_name='+', to='tenancy.tenantgroup'), - ), - migrations.AddField( - model_name='configcontext', - name='tenants', - field=models.ManyToManyField(blank=True, related_name='+', to='tenancy.tenant'), - ), - migrations.AddField( - model_name='cachedvalue', - name='object_type', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='contenttypes.contenttype'), - ), - migrations.AddField( - model_name='branch', - name='user', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), - ), - migrations.AddField( - model_name='bookmark', - name='object_type', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='contenttypes.contenttype'), - ), - migrations.AddField( - model_name='bookmark', - name='user', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL), - ), - migrations.AddConstraint( - model_name='webhook', - constraint=models.UniqueConstraint(fields=('payload_url', 'type_create', 'type_update', 'type_delete'), name='extras_webhook_unique_payload_url_types'), - ), - migrations.AddIndex( - model_name='taggeditem', - index=models.Index(fields=['content_type', 'object_id'], name='extras_tagg_content_717743_idx'), - ), - migrations.AddConstraint( - model_name='bookmark', - constraint=models.UniqueConstraint(fields=('object_type', 'object_id', 'user'), name='extras_bookmark_unique_per_object_and_user'), - ), - ] diff --git a/netbox/extras/migrations/0002_squashed_0059.py b/netbox/extras/migrations/0002_squashed_0059.py new file mode 100644 index 000000000..98bed255a --- /dev/null +++ b/netbox/extras/migrations/0002_squashed_0059.py @@ -0,0 +1,142 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0002_auto_20160622_1821'), + ('extras', '0001_initial'), + ('virtualization', '0001_virtualization'), + ('tenancy', '0001_initial'), + ] + + replaces = [ + ('extras', '0002_custom_fields'), + ('extras', '0003_exporttemplate_add_description'), + ('extras', '0004_topologymap_change_comma_to_semicolon'), + ('extras', '0005_useraction_add_bulk_create'), + ('extras', '0006_add_imageattachments'), + ('extras', '0007_unicode_literals'), + ('extras', '0008_reports'), + ('extras', '0009_topologymap_type'), + ('extras', '0010_customfield_filter_logic'), + ('extras', '0011_django2'), + ('extras', '0012_webhooks'), + ('extras', '0013_objectchange'), + ('extras', '0014_configcontexts'), + ('extras', '0015_remove_useraction'), + ('extras', '0016_exporttemplate_add_cable'), + ('extras', '0017_exporttemplate_mime_type_length'), + ('extras', '0018_exporttemplate_add_jinja2'), + ('extras', '0019_tag_taggeditem'), + ('extras', '0020_tag_data'), + ('extras', '0021_add_color_comments_changelog_to_tag'), + ('extras', '0022_custom_links'), + ('extras', '0023_fix_tag_sequences'), + ('extras', '0024_scripts'), + ('extras', '0025_objectchange_time_index'), + ('extras', '0026_webhook_ca_file_path'), + ('extras', '0027_webhook_additional_headers'), + ('extras', '0028_remove_topology_maps'), + ('extras', '0029_3569_customfield_fields'), + ('extras', '0030_3569_objectchange_fields'), + ('extras', '0031_3569_exporttemplate_fields'), + ('extras', '0032_3569_webhook_fields'), + ('extras', '0033_graph_type_template_language'), + ('extras', '0034_configcontext_tags'), + ('extras', '0035_deterministic_ordering'), + ('extras', '0036_contenttype_filters_to_q_objects'), + ('extras', '0037_configcontexts_clusters'), + ('extras', '0038_webhook_template_support'), + ('extras', '0039_update_features_content_types'), + ('extras', '0040_standardize_description'), + ('extras', '0041_tag_description'), + ('extras', '0042_customfield_manager'), + ('extras', '0043_report'), + ('extras', '0044_jobresult'), + ('extras', '0045_configcontext_changelog'), + ('extras', '0046_update_jsonfield'), + ('extras', '0047_tag_ordering'), + ('extras', '0048_exporttemplate_remove_template_language'), + ('extras', '0049_remove_graph'), + ('extras', '0050_customfield_changes'), + ('extras', '0051_migrate_customfields'), + ('extras', '0052_customfield_cleanup'), + ('extras', '0053_rename_webhook_obj_type'), + ('extras', '0054_standardize_models'), + ('extras', '0055_objectchange_data'), + ('extras', '0056_extend_configcontext'), + ('extras', '0057_customlink_rename_fields'), + ('extras', '0058_journalentry'), + ('extras', '0059_exporttemplate_as_attachment'), + ] + + operations = [ + migrations.AddField( + model_name='configcontext', + name='cluster_groups', + field=models.ManyToManyField(blank=True, related_name='+', to='virtualization.ClusterGroup'), + ), + migrations.AddField( + model_name='configcontext', + name='clusters', + field=models.ManyToManyField(blank=True, related_name='+', to='virtualization.Cluster'), + ), + migrations.AddField( + model_name='configcontext', + name='device_types', + field=models.ManyToManyField(blank=True, related_name='+', to='dcim.DeviceType'), + ), + migrations.AddField( + model_name='configcontext', + name='platforms', + field=models.ManyToManyField(blank=True, related_name='+', to='dcim.Platform'), + ), + migrations.AddField( + model_name='configcontext', + name='regions', + field=models.ManyToManyField(blank=True, related_name='+', to='dcim.Region'), + ), + migrations.AddField( + model_name='configcontext', + name='roles', + field=models.ManyToManyField(blank=True, related_name='+', to='dcim.DeviceRole'), + ), + migrations.AddField( + model_name='configcontext', + name='site_groups', + field=models.ManyToManyField(blank=True, related_name='+', to='dcim.SiteGroup'), + ), + migrations.AddField( + model_name='configcontext', + name='sites', + field=models.ManyToManyField(blank=True, related_name='+', to='dcim.Site'), + ), + migrations.AddField( + model_name='configcontext', + name='tags', + field=models.ManyToManyField(blank=True, related_name='+', to='extras.Tag'), + ), + migrations.AddField( + model_name='configcontext', + name='tenant_groups', + field=models.ManyToManyField(blank=True, related_name='+', to='tenancy.TenantGroup'), + ), + migrations.AddField( + model_name='configcontext', + name='tenants', + field=models.ManyToManyField(blank=True, related_name='+', to='tenancy.Tenant'), + ), + migrations.AlterUniqueTogether( + name='webhook', + unique_together={('payload_url', 'type_create', 'type_update', 'type_delete')}, + ), + migrations.AlterIndexTogether( + name='taggeditem', + index_together={('content_type', 'object_id')}, + ), + migrations.AlterUniqueTogether( + name='exporttemplate', + unique_together={('content_type', 'name')}, + ), + ] diff --git a/netbox/extras/migrations/0060_customlink_button_class.py b/netbox/extras/migrations/0060_customlink_button_class.py new file mode 100644 index 000000000..d54df3042 --- /dev/null +++ b/netbox/extras/migrations/0060_customlink_button_class.py @@ -0,0 +1,16 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0059_exporttemplate_as_attachment'), + ] + + operations = [ + migrations.AlterField( + model_name='customlink', + name='button_class', + field=models.CharField(default='outline-dark', max_length=30), + ), + ] diff --git a/netbox/extras/migrations/0061_extras_change_logging.py b/netbox/extras/migrations/0061_extras_change_logging.py new file mode 100644 index 000000000..4ee532fd5 --- /dev/null +++ b/netbox/extras/migrations/0061_extras_change_logging.py @@ -0,0 +1,51 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0060_customlink_button_class'), + ] + + operations = [ + migrations.AddField( + model_name='customfield', + name='created', + field=models.DateField(auto_now_add=True, null=True), + ), + migrations.AddField( + model_name='customfield', + name='last_updated', + field=models.DateTimeField(auto_now=True, null=True), + ), + migrations.AddField( + model_name='customlink', + name='created', + field=models.DateField(auto_now_add=True, null=True), + ), + migrations.AddField( + model_name='customlink', + name='last_updated', + field=models.DateTimeField(auto_now=True, null=True), + ), + migrations.AddField( + model_name='exporttemplate', + name='created', + field=models.DateField(auto_now_add=True, null=True), + ), + migrations.AddField( + model_name='exporttemplate', + name='last_updated', + field=models.DateTimeField(auto_now=True, null=True), + ), + migrations.AddField( + model_name='webhook', + name='created', + field=models.DateField(auto_now_add=True, null=True), + ), + migrations.AddField( + model_name='webhook', + name='last_updated', + field=models.DateTimeField(auto_now=True, null=True), + ), + ] diff --git a/netbox/extras/migrations/0062_clear_secrets_changelog.py b/netbox/extras/migrations/0062_clear_secrets_changelog.py new file mode 100644 index 000000000..e76fc8d34 --- /dev/null +++ b/netbox/extras/migrations/0062_clear_secrets_changelog.py @@ -0,0 +1,26 @@ +from django.db import migrations + + +def clear_secrets_changelog(apps, schema_editor): + """ + Delete all ObjectChange records referencing a model within the old secrets app (pre-v3.0). + """ + ContentType = apps.get_model('contenttypes', 'ContentType') + ObjectChange = apps.get_model('extras', 'ObjectChange') + + content_type_ids = ContentType.objects.filter(app_label='secrets').values_list('id', flat=True) + ObjectChange.objects.filter(changed_object_type__in=content_type_ids).delete() + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0061_extras_change_logging'), + ] + + operations = [ + migrations.RunPython( + code=clear_secrets_changelog, + reverse_code=migrations.RunPython.noop + ), + ] diff --git a/netbox/extras/migrations/0063_webhook_conditions.py b/netbox/extras/migrations/0063_webhook_conditions.py new file mode 100644 index 000000000..8cc5b1bd3 --- /dev/null +++ b/netbox/extras/migrations/0063_webhook_conditions.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.8 on 2021-10-22 20:37 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0062_clear_secrets_changelog'), + ] + + operations = [ + migrations.AddField( + model_name='webhook', + name='conditions', + field=models.JSONField(blank=True, null=True), + ), + ] diff --git a/netbox/extras/migrations/0064_configrevision.py b/netbox/extras/migrations/0064_configrevision.py new file mode 100644 index 000000000..c3fce8abe --- /dev/null +++ b/netbox/extras/migrations/0064_configrevision.py @@ -0,0 +1,20 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0063_webhook_conditions'), + ] + + operations = [ + migrations.CreateModel( + name='ConfigRevision', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)), + ('created', models.DateTimeField(auto_now_add=True)), + ('comment', models.CharField(blank=True, max_length=200)), + ('data', models.JSONField(blank=True, null=True)), + ], + ), + ] diff --git a/netbox/extras/migrations/0065_imageattachment_change_logging.py b/netbox/extras/migrations/0065_imageattachment_change_logging.py new file mode 100644 index 000000000..dc623e46c --- /dev/null +++ b/netbox/extras/migrations/0065_imageattachment_change_logging.py @@ -0,0 +1,16 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0064_configrevision'), + ] + + operations = [ + migrations.AddField( + model_name='imageattachment', + name='last_updated', + field=models.DateTimeField(auto_now=True, null=True), + ), + ] diff --git a/netbox/extras/migrations/0066_customfield_name_validation.py b/netbox/extras/migrations/0066_customfield_name_validation.py new file mode 100644 index 000000000..3d2c51399 --- /dev/null +++ b/netbox/extras/migrations/0066_customfield_name_validation.py @@ -0,0 +1,34 @@ +import django.core.validators +from django.db import migrations, models +import re + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0065_imageattachment_change_logging'), + ] + + operations = [ + migrations.AlterField( + model_name='customfield', + name='name', + field=models.CharField( + max_length=50, + unique=True, + validators=[ + django.core.validators.RegexValidator( + flags=re.RegexFlag['IGNORECASE'], + message='Only alphanumeric characters and underscores are allowed.', + regex='^[a-z0-9_]+$', + ), + django.core.validators.RegexValidator( + flags=re.RegexFlag['IGNORECASE'], + inverse_match=True, + message='Double underscores are not permitted in custom field names.', + regex=r'__', + ), + ], + ), + ), + ] diff --git a/netbox/extras/migrations/0067_customfield_min_max_values.py b/netbox/extras/migrations/0067_customfield_min_max_values.py new file mode 100644 index 000000000..cec4f6ae0 --- /dev/null +++ b/netbox/extras/migrations/0067_customfield_min_max_values.py @@ -0,0 +1,21 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0066_customfield_name_validation'), + ] + + operations = [ + migrations.AlterField( + model_name='customfield', + name='validation_maximum', + field=models.IntegerField(blank=True, null=True), + ), + migrations.AlterField( + model_name='customfield', + name='validation_minimum', + field=models.IntegerField(blank=True, null=True), + ), + ] diff --git a/netbox/extras/migrations/0068_configcontext_cluster_types.py b/netbox/extras/migrations/0068_configcontext_cluster_types.py new file mode 100644 index 000000000..3d314991d --- /dev/null +++ b/netbox/extras/migrations/0068_configcontext_cluster_types.py @@ -0,0 +1,18 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0145_site_remove_deprecated_fields'), + ('virtualization', '0026_vminterface_bridge'), + ('extras', '0067_customfield_min_max_values'), + ] + + operations = [ + migrations.AddField( + model_name='configcontext', + name='cluster_types', + field=models.ManyToManyField(blank=True, related_name='+', to='virtualization.ClusterType'), + ), + ] diff --git a/netbox/extras/migrations/0069_custom_object_field.py b/netbox/extras/migrations/0069_custom_object_field.py new file mode 100644 index 000000000..720e21edc --- /dev/null +++ b/netbox/extras/migrations/0069_custom_object_field.py @@ -0,0 +1,18 @@ +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('extras', '0068_configcontext_cluster_types'), + ] + + operations = [ + migrations.AddField( + model_name='customfield', + name='object_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='contenttypes.contenttype'), + ), + ] diff --git a/netbox/extras/migrations/0070_customlink_enabled.py b/netbox/extras/migrations/0070_customlink_enabled.py new file mode 100644 index 000000000..839a4dba5 --- /dev/null +++ b/netbox/extras/migrations/0070_customlink_enabled.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.11 on 2022-01-10 16:45 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0069_custom_object_field'), + ] + + operations = [ + migrations.AddField( + model_name='customlink', + name='enabled', + field=models.BooleanField(default=True), + ), + ] diff --git a/netbox/extras/migrations/0071_standardize_id_fields.py b/netbox/extras/migrations/0071_standardize_id_fields.py new file mode 100644 index 000000000..63e3051d8 --- /dev/null +++ b/netbox/extras/migrations/0071_standardize_id_fields.py @@ -0,0 +1,89 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0070_customlink_enabled'), + ] + + operations = [ + # Model IDs + migrations.AlterField( + model_name='configcontext', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='configrevision', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='customfield', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='customlink', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='exporttemplate', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='imageattachment', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='jobresult', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='journalentry', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='objectchange', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='taggeditem', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='webhook', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + + # GFK IDs + migrations.AlterField( + model_name='imageattachment', + name='object_id', + field=models.PositiveBigIntegerField(), + ), + migrations.AlterField( + model_name='journalentry', + name='assigned_object_id', + field=models.PositiveBigIntegerField(), + ), + migrations.AlterField( + model_name='objectchange', + name='changed_object_id', + field=models.PositiveBigIntegerField(), + ), + migrations.AlterField( + model_name='objectchange', + name='related_object_id', + field=models.PositiveBigIntegerField(blank=True, null=True), + ), + ] diff --git a/netbox/extras/migrations/0072_created_datetimefield.py b/netbox/extras/migrations/0072_created_datetimefield.py new file mode 100644 index 000000000..827e99e54 --- /dev/null +++ b/netbox/extras/migrations/0072_created_datetimefield.py @@ -0,0 +1,53 @@ +# Generated by Django 4.0.2 on 2022-02-08 18:54 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0071_standardize_id_fields'), + ] + + operations = [ + migrations.AlterField( + model_name='configcontext', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='customfield', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='customlink', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='exporttemplate', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='imageattachment', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='journalentry', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='tag', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='webhook', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + ] diff --git a/netbox/extras/migrations/0073_journalentry_tags_custom_fields.py b/netbox/extras/migrations/0073_journalentry_tags_custom_fields.py new file mode 100644 index 000000000..5f2d7f7f3 --- /dev/null +++ b/netbox/extras/migrations/0073_journalentry_tags_custom_fields.py @@ -0,0 +1,23 @@ +from utilities.json import CustomFieldJSONEncoder +from django.db import migrations, models +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0072_created_datetimefield'), + ] + + operations = [ + migrations.AddField( + model_name='journalentry', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder), + ), + migrations.AddField( + model_name='journalentry', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + ] diff --git a/netbox/extras/migrations/0074_customfield_extensions.py b/netbox/extras/migrations/0074_customfield_extensions.py new file mode 100644 index 000000000..6ca8b958f --- /dev/null +++ b/netbox/extras/migrations/0074_customfield_extensions.py @@ -0,0 +1,27 @@ +# Generated by Django 4.0.4 on 2022-04-15 17:13 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0073_journalentry_tags_custom_fields'), + ] + + operations = [ + migrations.AlterModelOptions( + name='customfield', + options={'ordering': ['group_name', 'weight', 'name']}, + ), + migrations.AddField( + model_name='customfield', + name='group_name', + field=models.CharField(blank=True, max_length=50), + ), + migrations.AddField( + model_name='customfield', + name='ui_visibility', + field=models.CharField(default='read-write', max_length=50), + ), + ] diff --git a/netbox/extras/migrations/0075_configcontext_locations.py b/netbox/extras/migrations/0075_configcontext_locations.py new file mode 100644 index 000000000..853aec4f7 --- /dev/null +++ b/netbox/extras/migrations/0075_configcontext_locations.py @@ -0,0 +1,19 @@ +# Generated by Django 4.0.5 on 2022-06-22 19:13 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0156_location_status'), + ('extras', '0074_customfield_extensions'), + ] + + operations = [ + migrations.AddField( + model_name='configcontext', + name='locations', + field=models.ManyToManyField(blank=True, related_name='+', to='dcim.location'), + ), + ] diff --git a/netbox/extras/migrations/0076_tag_slug_unicode.py b/netbox/extras/migrations/0076_tag_slug_unicode.py new file mode 100644 index 000000000..3f4922963 --- /dev/null +++ b/netbox/extras/migrations/0076_tag_slug_unicode.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0.6 on 2022-07-14 15:51 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0075_configcontext_locations'), + ] + + operations = [ + migrations.AlterField( + model_name='tag', + name='slug', + field=models.SlugField(allow_unicode=True, max_length=100, unique=True), + ), + ] diff --git a/netbox/extras/migrations/0077_customlink_extend_text_and_url.py b/netbox/extras/migrations/0077_customlink_extend_text_and_url.py new file mode 100644 index 000000000..c08948aa6 --- /dev/null +++ b/netbox/extras/migrations/0077_customlink_extend_text_and_url.py @@ -0,0 +1,21 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0076_tag_slug_unicode'), + ] + + operations = [ + migrations.AlterField( + model_name='customlink', + name='link_text', + field=models.TextField(), + ), + migrations.AlterField( + model_name='customlink', + name='link_url', + field=models.TextField(), + ), + ] diff --git a/netbox/extras/migrations/0078_unique_constraints.py b/netbox/extras/migrations/0078_unique_constraints.py new file mode 100644 index 000000000..4a56831a7 --- /dev/null +++ b/netbox/extras/migrations/0078_unique_constraints.py @@ -0,0 +1,27 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0077_customlink_extend_text_and_url'), + ] + + operations = [ + migrations.AlterUniqueTogether( + name='exporttemplate', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='webhook', + unique_together=set(), + ), + migrations.AddConstraint( + model_name='exporttemplate', + constraint=models.UniqueConstraint(fields=('content_type', 'name'), name='extras_exporttemplate_unique_content_type_name'), + ), + migrations.AddConstraint( + model_name='webhook', + constraint=models.UniqueConstraint(fields=('payload_url', 'type_create', 'type_update', 'type_delete'), name='extras_webhook_unique_payload_url_types'), + ), + ] diff --git a/netbox/extras/migrations/0079_scheduled_jobs.py b/netbox/extras/migrations/0079_scheduled_jobs.py new file mode 100644 index 000000000..f9f8c6357 --- /dev/null +++ b/netbox/extras/migrations/0079_scheduled_jobs.py @@ -0,0 +1,31 @@ +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0078_unique_constraints'), + ] + + operations = [ + migrations.AddField( + model_name='jobresult', + name='scheduled', + field=models.DateTimeField(blank=True, null=True), + ), + migrations.AddField( + model_name='jobresult', + name='interval', + field=models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)]), + ), + migrations.AddField( + model_name='jobresult', + name='started', + field=models.DateTimeField(blank=True, null=True), + ), + migrations.AlterModelOptions( + name='jobresult', + options={'ordering': ['-created']}, + ), + ] diff --git a/netbox/extras/migrations/0080_customlink_content_types.py b/netbox/extras/migrations/0080_customlink_content_types.py new file mode 100644 index 000000000..7f8456c67 --- /dev/null +++ b/netbox/extras/migrations/0080_customlink_content_types.py @@ -0,0 +1,32 @@ +from django.db import migrations, models + + +def copy_content_types(apps, schema_editor): + CustomLink = apps.get_model('extras', 'CustomLink') + + for customlink in CustomLink.objects.all(): + customlink.content_types.set([customlink.content_type]) + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('extras', '0079_scheduled_jobs'), + ] + + operations = [ + migrations.AddField( + model_name='customlink', + name='content_types', + field=models.ManyToManyField(related_name='custom_links', to='contenttypes.contenttype'), + ), + migrations.RunPython( + code=copy_content_types, + reverse_code=migrations.RunPython.noop + ), + migrations.RemoveField( + model_name='customlink', + name='content_type', + ), + ] diff --git a/netbox/extras/migrations/0081_exporttemplate_content_types.py b/netbox/extras/migrations/0081_exporttemplate_content_types.py new file mode 100644 index 000000000..afa21c5b8 --- /dev/null +++ b/netbox/extras/migrations/0081_exporttemplate_content_types.py @@ -0,0 +1,40 @@ +from django.db import migrations, models + + +def copy_content_types(apps, schema_editor): + ExportTemplate = apps.get_model('extras', 'ExportTemplate') + + for et in ExportTemplate.objects.all(): + et.content_types.set([et.content_type]) + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('extras', '0080_customlink_content_types'), + ] + + operations = [ + migrations.AddField( + model_name='exporttemplate', + name='content_types', + field=models.ManyToManyField(related_name='export_templates', to='contenttypes.contenttype'), + ), + migrations.RunPython( + code=copy_content_types, + reverse_code=migrations.RunPython.noop + ), + migrations.RemoveConstraint( + model_name='exporttemplate', + name='extras_exporttemplate_unique_content_type_name', + ), + migrations.RemoveField( + model_name='exporttemplate', + name='content_type', + ), + migrations.AlterModelOptions( + name='exporttemplate', + options={'ordering': ('name',)}, + ), + ] diff --git a/netbox/extras/migrations/0082_savedfilter.py b/netbox/extras/migrations/0082_savedfilter.py new file mode 100644 index 000000000..e2626ec6a --- /dev/null +++ b/netbox/extras/migrations/0082_savedfilter.py @@ -0,0 +1,35 @@ +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('contenttypes', '0002_remove_content_type_name'), + ('extras', '0081_exporttemplate_content_types'), + ] + + operations = [ + migrations.CreateModel( + name='SavedFilter', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('name', models.CharField(max_length=100, unique=True)), + ('slug', models.SlugField(max_length=100, unique=True)), + ('description', models.CharField(blank=True, max_length=200)), + ('weight', models.PositiveSmallIntegerField(default=100)), + ('enabled', models.BooleanField(default=True)), + ('shared', models.BooleanField(default=True)), + ('parameters', models.JSONField()), + ('content_types', models.ManyToManyField(related_name='saved_filters', to='contenttypes.contenttype')), + ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'ordering': ('weight', 'name'), + }, + ), + ] diff --git a/netbox/extras/migrations/0083_search.py b/netbox/extras/migrations/0083_search.py new file mode 100644 index 000000000..4c7ae1084 --- /dev/null +++ b/netbox/extras/migrations/0083_search.py @@ -0,0 +1,44 @@ +import uuid + +import django.db.models.deletion +import django.db.models.lookups +from django.db import migrations, models +import extras.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('circuits', '0041_standardize_description_comments'), + ('contenttypes', '0002_remove_content_type_name'), + ('dcim', '0166_virtualdevicecontext'), + ('extras', '0082_savedfilter'), + ('ipam', '0063_standardize_description_comments'), + ('tenancy', '0009_standardize_description_comments'), + ('virtualization', '0034_standardize_description_comments'), + ('wireless', '0008_wirelesslan_status'), + ] + + operations = [ + migrations.AddField( + model_name='customfield', + name='search_weight', + field=models.PositiveSmallIntegerField(default=1000), + ), + migrations.CreateModel( + name='CachedValue', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('timestamp', models.DateTimeField(auto_now_add=True)), + ('object_id', models.PositiveBigIntegerField()), + ('field', models.CharField(max_length=200)), + ('type', models.CharField(max_length=30)), + ('value', extras.fields.CachedValueField()), + ('weight', models.PositiveSmallIntegerField(default=1000)), + ('object_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='contenttypes.contenttype')), + ], + options={ + 'ordering': ('weight', 'object_type', 'object_id'), + }, + ), + ] diff --git a/netbox/extras/migrations/0084_staging.py b/netbox/extras/migrations/0084_staging.py new file mode 100644 index 000000000..3129d7f5b --- /dev/null +++ b/netbox/extras/migrations/0084_staging.py @@ -0,0 +1,45 @@ +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('extras', '0083_search'), + ] + + operations = [ + migrations.CreateModel( + name='Branch', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('name', models.CharField(max_length=100, unique=True)), + ('description', models.CharField(blank=True, max_length=200)), + ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'ordering': ('name',), + }, + ), + migrations.CreateModel( + name='StagedChange', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('action', models.CharField(max_length=20)), + ('object_id', models.PositiveBigIntegerField(blank=True, null=True)), + ('data', models.JSONField(blank=True, null=True)), + ('branch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='staged_changes', to='extras.branch')), + ('object_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='contenttypes.contenttype')), + ], + options={ + 'ordering': ('pk',), + }, + ), + ] diff --git a/netbox/extras/migrations/0085_synced_data.py b/netbox/extras/migrations/0085_synced_data.py new file mode 100644 index 000000000..372845490 --- /dev/null +++ b/netbox/extras/migrations/0085_synced_data.py @@ -0,0 +1,65 @@ +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0001_initial'), + ('extras', '0084_staging'), + ] + + operations = [ + # ConfigContexts + migrations.AddField( + model_name='configcontext', + name='data_file', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='core.datafile'), + ), + migrations.AddField( + model_name='configcontext', + name='data_path', + field=models.CharField(blank=True, editable=False, max_length=1000), + ), + migrations.AddField( + model_name='configcontext', + name='data_source', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='core.datasource'), + ), + migrations.AddField( + model_name='configcontext', + name='auto_sync_enabled', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='configcontext', + name='data_synced', + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + # ExportTemplates + migrations.AddField( + model_name='exporttemplate', + name='data_file', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='core.datafile'), + ), + migrations.AddField( + model_name='exporttemplate', + name='data_path', + field=models.CharField(blank=True, editable=False, max_length=1000), + ), + migrations.AddField( + model_name='exporttemplate', + name='data_source', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='core.datasource'), + ), + migrations.AddField( + model_name='exporttemplate', + name='auto_sync_enabled', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='exporttemplate', + name='data_synced', + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + ] diff --git a/netbox/extras/migrations/0086_configtemplate.py b/netbox/extras/migrations/0086_configtemplate.py new file mode 100644 index 000000000..32d4e9858 --- /dev/null +++ b/netbox/extras/migrations/0086_configtemplate.py @@ -0,0 +1,35 @@ +from django.db import migrations, models +import django.db.models.deletion +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0001_initial'), + ('extras', '0085_synced_data'), + ] + + operations = [ + migrations.CreateModel( + name='ConfigTemplate', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('data_path', models.CharField(blank=True, editable=False, max_length=1000)), + ('data_synced', models.DateTimeField(blank=True, editable=False, null=True)), + ('name', models.CharField(max_length=100)), + ('description', models.CharField(blank=True, max_length=200)), + ('template_code', models.TextField()), + ('environment_params', models.JSONField(blank=True, default=dict, null=True)), + ('data_file', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='core.datafile')), + ('data_source', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='core.datasource')), + ('auto_sync_enabled', models.BooleanField(default=False)), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ], + options={ + 'ordering': ('name',), + }, + ), + ] diff --git a/netbox/extras/migrations/0087_dashboard.py b/netbox/extras/migrations/0087_dashboard.py new file mode 100644 index 000000000..0c048c5ef --- /dev/null +++ b/netbox/extras/migrations/0087_dashboard.py @@ -0,0 +1,25 @@ +# Generated by Django 4.1.7 on 2023-02-24 00:56 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('extras', '0086_configtemplate'), + ] + + operations = [ + migrations.CreateModel( + name='Dashboard', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('layout', models.JSONField(default=list)), + ('config', models.JSONField(default=dict)), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='dashboard', to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/netbox/extras/migrations/0088_jobresult_webhooks.py b/netbox/extras/migrations/0088_jobresult_webhooks.py new file mode 100644 index 000000000..112bcca8c --- /dev/null +++ b/netbox/extras/migrations/0088_jobresult_webhooks.py @@ -0,0 +1,23 @@ +# Generated by Django 4.1.7 on 2023-02-28 19:11 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0087_dashboard'), + ] + + operations = [ + migrations.AddField( + model_name='webhook', + name='type_job_end', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='webhook', + name='type_job_start', + field=models.BooleanField(default=False), + ), + ] diff --git a/netbox/extras/migrations/0089_customfield_is_cloneable.py b/netbox/extras/migrations/0089_customfield_is_cloneable.py new file mode 100644 index 000000000..7f577b45a --- /dev/null +++ b/netbox/extras/migrations/0089_customfield_is_cloneable.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.2 on 2022-11-17 18:25 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0088_jobresult_webhooks'), + ] + + operations = [ + migrations.AddField( + model_name='customfield', + name='is_cloneable', + field=models.BooleanField(default=False), + ), + ] diff --git a/netbox/extras/migrations/0090_objectchange_index_request_id.py b/netbox/extras/migrations/0090_objectchange_index_request_id.py new file mode 100644 index 000000000..00e8fde42 --- /dev/null +++ b/netbox/extras/migrations/0090_objectchange_index_request_id.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.7 on 2023-03-16 20:06 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0089_customfield_is_cloneable'), + ] + + operations = [ + migrations.AlterField( + model_name='objectchange', + name='request_id', + field=models.UUIDField(db_index=True, editable=False), + ), + ] diff --git a/netbox/extras/migrations/0091_create_managedfiles.py b/netbox/extras/migrations/0091_create_managedfiles.py new file mode 100644 index 000000000..79a80821f --- /dev/null +++ b/netbox/extras/migrations/0091_create_managedfiles.py @@ -0,0 +1,79 @@ +import os +import pkgutil + +from django.conf import settings +from django.db import migrations, models +import extras.models.mixins + + +def create_files(cls, root_name, root_path): + + modules = list(pkgutil.iter_modules([root_path])) + filenames = [] + for importer, module_name, ispkg in modules: + try: + module = importer.find_module(module_name).load_module(module_name) + rel_path = os.path.relpath(module.__file__, root_path) + filenames.append(rel_path) + except ImportError: + pass + + managed_files = [ + cls(file_root=root_name, file_path=filename) + for filename in filenames + ] + cls.objects.bulk_create(managed_files) + + +def replicate_scripts(apps, schema_editor): + ScriptModule = apps.get_model('extras', 'ScriptModule') + create_files(ScriptModule, 'scripts', settings.SCRIPTS_ROOT) + + +def replicate_reports(apps, schema_editor): + ReportModule = apps.get_model('extras', 'ReportModule') + create_files(ReportModule, 'reports', settings.REPORTS_ROOT) + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0002_managedfile'), + ('extras', '0090_objectchange_index_request_id'), + ] + + operations = [ + # Create proxy models + migrations.CreateModel( + name='ReportModule', + fields=[ + ], + options={ + 'proxy': True, + 'indexes': [], + 'constraints': [], + }, + bases=(extras.models.mixins.PythonModuleMixin, 'core.managedfile', models.Model), + ), + migrations.CreateModel( + name='ScriptModule', + fields=[ + ], + options={ + 'proxy': True, + 'indexes': [], + 'constraints': [], + }, + bases=(extras.models.mixins.PythonModuleMixin, 'core.managedfile', models.Model), + ), + + # Instantiate ManagedFiles to represent scripts & reports + migrations.RunPython( + code=replicate_scripts, + reverse_code=migrations.RunPython.noop + ), + migrations.RunPython( + code=replicate_reports, + reverse_code=migrations.RunPython.noop + ), + ] diff --git a/netbox/extras/migrations/0092_delete_jobresult.py b/netbox/extras/migrations/0092_delete_jobresult.py new file mode 100644 index 000000000..c1b121c69 --- /dev/null +++ b/netbox/extras/migrations/0092_delete_jobresult.py @@ -0,0 +1,16 @@ +# Generated by Django 4.1.7 on 2023-03-27 17:31 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0091_create_managedfiles'), + ] + + operations = [ + migrations.DeleteModel( + name='JobResult', + ), + ] diff --git a/netbox/extras/migrations/0093_configrevision_ordering.py b/netbox/extras/migrations/0093_configrevision_ordering.py new file mode 100644 index 000000000..a4e875e6d --- /dev/null +++ b/netbox/extras/migrations/0093_configrevision_ordering.py @@ -0,0 +1,17 @@ +# Generated by Django 4.1.9 on 2023-06-22 14:14 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0092_delete_jobresult'), + ] + + operations = [ + migrations.AlterModelOptions( + name='configrevision', + options={'ordering': ['-created']}, + ), + ] diff --git a/netbox/extras/migrations/0094_tag_object_types.py b/netbox/extras/migrations/0094_tag_object_types.py new file mode 100644 index 000000000..8bb760980 --- /dev/null +++ b/netbox/extras/migrations/0094_tag_object_types.py @@ -0,0 +1,22 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('extras', '0093_configrevision_ordering'), + ] + + operations = [ + migrations.AddField( + model_name='tag', + name='object_types', + field=models.ManyToManyField(blank=True, related_name='+', to='contenttypes.contenttype'), + ), + migrations.RenameIndex( + model_name='taggeditem', + new_name='extras_tagg_content_717743_idx', + old_fields=('content_type', 'object_id'), + ), + ] diff --git a/netbox/extras/migrations/0095_bookmarks.py b/netbox/extras/migrations/0095_bookmarks.py new file mode 100644 index 000000000..54c14c496 --- /dev/null +++ b/netbox/extras/migrations/0095_bookmarks.py @@ -0,0 +1,34 @@ +# Generated by Django 4.1.9 on 2023-06-29 14:07 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('contenttypes', '0002_remove_content_type_name'), + ('extras', '0094_tag_object_types'), + ] + + operations = [ + migrations.CreateModel( + name='Bookmark', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('created', models.DateTimeField(auto_now_add=True)), + ('object_id', models.PositiveBigIntegerField()), + ('object_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='contenttypes.contenttype')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'ordering': ('created', 'pk'), + }, + ), + migrations.AddConstraint( + model_name='bookmark', + constraint=models.UniqueConstraint(fields=('object_type', 'object_id', 'user'), name='extras_bookmark_unique_per_object_and_user'), + ), + ] diff --git a/netbox/extras/migrations/0096_customfieldchoiceset.py b/netbox/extras/migrations/0096_customfieldchoiceset.py new file mode 100644 index 000000000..1984e17f8 --- /dev/null +++ b/netbox/extras/migrations/0096_customfieldchoiceset.py @@ -0,0 +1,62 @@ +import django.contrib.postgres.fields +from django.db import migrations, models + +from extras.choices import CustomFieldTypeChoices + + +def create_choice_sets(apps, schema_editor): + """ + Create a CustomFieldChoiceSet for each CustomField with choices defined. + """ + CustomField = apps.get_model('extras', 'CustomField') + CustomFieldChoiceSet = apps.get_model('extras', 'CustomFieldChoiceSet') + + # Create custom field choice sets + choice_fields = CustomField.objects.filter( + type__in=(CustomFieldTypeChoices.TYPE_SELECT, CustomFieldTypeChoices.TYPE_MULTISELECT), + choices__len__gt=0 + ) + for cf in choice_fields: + choiceset = CustomFieldChoiceSet.objects.create( + name=f'{cf.name} Choices', + extra_choices=tuple(zip(cf.choices, cf.choices)) # Convert list to tuple of two-tuples + ) + cf.choice_set = choiceset + + # Update custom fields to point to new choice sets + CustomField.objects.bulk_update(choice_fields, ['choice_set']) + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0095_bookmarks'), + ] + + operations = [ + migrations.CreateModel( + name='CustomFieldChoiceSet', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('name', models.CharField(max_length=100, unique=True)), + ('description', models.CharField(blank=True, max_length=200)), + ('base_choices', models.CharField(blank=True, max_length=50)), + ('extra_choices', django.contrib.postgres.fields.ArrayField(base_field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=100), size=2), blank=True, null=True, size=None)), + ('order_alphabetically', models.BooleanField(default=False)), + ], + options={ + 'ordering': ('name',), + }, + ), + migrations.AddField( + model_name='customfield', + name='choice_set', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='choices_for', to='extras.customfieldchoiceset'), + ), + migrations.RunPython( + code=create_choice_sets, + reverse_code=migrations.RunPython.noop + ), + ] diff --git a/netbox/extras/migrations/0097_customfield_remove_choices.py b/netbox/extras/migrations/0097_customfield_remove_choices.py new file mode 100644 index 000000000..f3e8c547e --- /dev/null +++ b/netbox/extras/migrations/0097_customfield_remove_choices.py @@ -0,0 +1,17 @@ +# Generated by Django 4.1.10 on 2023-07-17 15:22 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0096_customfieldchoiceset'), + ] + + operations = [ + migrations.RemoveField( + model_name='customfield', + name='choices', + ), + ] diff --git a/netbox/extras/migrations/0098_webhook_custom_field_data_webhook_tags.py b/netbox/extras/migrations/0098_webhook_custom_field_data_webhook_tags.py new file mode 100644 index 000000000..3fd294388 --- /dev/null +++ b/netbox/extras/migrations/0098_webhook_custom_field_data_webhook_tags.py @@ -0,0 +1,25 @@ +# Generated by Django 4.1.10 on 2023-08-01 16:32 + +from django.db import migrations, models +import taggit.managers +import utilities.json + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0097_customfield_remove_choices'), + ] + + operations = [ + migrations.AddField( + model_name='webhook', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder), + ), + migrations.AddField( + model_name='webhook', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + ] diff --git a/netbox/ipam/migrations/0001_initial.py b/netbox/ipam/migrations/0001_initial.py deleted file mode 100644 index 399909457..000000000 --- a/netbox/ipam/migrations/0001_initial.py +++ /dev/null @@ -1,362 +0,0 @@ -import django.contrib.postgres.fields -import django.core.validators -from django.db import migrations, models -import ipam.fields -import ipam.models.ip -import taggit.managers -import utilities.json - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ('extras', '0001_initial'), - ] - - operations = [ - migrations.CreateModel( - name='Aggregate', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('prefix', ipam.fields.IPNetworkField()), - ('date_added', models.DateField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'aggregate', - 'verbose_name_plural': 'aggregates', - 'ordering': ('prefix', 'pk'), - }, - bases=(ipam.models.ip.GetAvailablePrefixesMixin, models.Model), - ), - migrations.CreateModel( - name='ASN', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('asn', ipam.fields.ASNField(unique=True)), - ], - options={ - 'verbose_name': 'ASN', - 'verbose_name_plural': 'ASNs', - 'ordering': ['asn'], - }, - ), - migrations.CreateModel( - name='ASNRange', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('name', models.CharField(max_length=100, unique=True)), - ('slug', models.SlugField(max_length=100, unique=True)), - ('start', ipam.fields.ASNField()), - ('end', ipam.fields.ASNField()), - ], - options={ - 'verbose_name': 'ASN range', - 'verbose_name_plural': 'ASN ranges', - 'ordering': ('name',), - }, - ), - migrations.CreateModel( - name='FHRPGroup', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('group_id', models.PositiveSmallIntegerField()), - ('name', models.CharField(blank=True, max_length=100)), - ('protocol', models.CharField(max_length=50)), - ('auth_type', models.CharField(blank=True, max_length=50)), - ('auth_key', models.CharField(blank=True, max_length=255)), - ], - options={ - 'verbose_name': 'FHRP group', - 'verbose_name_plural': 'FHRP groups', - 'ordering': ['protocol', 'group_id', 'pk'], - }, - ), - migrations.CreateModel( - name='FHRPGroupAssignment', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('interface_id', models.PositiveBigIntegerField()), - ('priority', models.PositiveSmallIntegerField(validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(255)])), - ], - options={ - 'verbose_name': 'FHRP group assignment', - 'verbose_name_plural': 'FHRP group assignments', - 'ordering': ('-priority', 'pk'), - }, - ), - migrations.CreateModel( - name='IPAddress', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('address', ipam.fields.IPAddressField()), - ('status', models.CharField(default='active', max_length=50)), - ('role', models.CharField(blank=True, max_length=50)), - ('assigned_object_id', models.PositiveBigIntegerField(blank=True, null=True)), - ('dns_name', models.CharField(blank=True, max_length=255, validators=[django.core.validators.RegexValidator(code='invalid', message='Only alphanumeric characters, asterisks, hyphens, periods, and underscores are allowed in DNS names', regex='^([0-9A-Za-z_-]+|\\*)(\\.[0-9A-Za-z_-]+)*\\.?$')])), - ], - options={ - 'verbose_name': 'IP address', - 'verbose_name_plural': 'IP addresses', - 'ordering': ('address', 'pk'), - }, - ), - migrations.CreateModel( - name='IPRange', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('start_address', ipam.fields.IPAddressField()), - ('end_address', ipam.fields.IPAddressField()), - ('size', models.PositiveIntegerField(editable=False)), - ('status', models.CharField(default='active', max_length=50)), - ('mark_utilized', models.BooleanField(default=False)), - ], - options={ - 'verbose_name': 'IP range', - 'verbose_name_plural': 'IP ranges', - 'ordering': (models.OrderBy(models.F('vrf'), nulls_first=True), 'start_address', 'pk'), - }, - ), - migrations.CreateModel( - name='L2VPN', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('name', models.CharField(max_length=100, unique=True)), - ('slug', models.SlugField(max_length=100, unique=True)), - ('type', models.CharField(max_length=50)), - ('identifier', models.BigIntegerField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'L2VPN', - 'verbose_name_plural': 'L2VPNs', - 'ordering': ('name', 'identifier'), - }, - ), - migrations.CreateModel( - name='L2VPNTermination', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('assigned_object_id', models.PositiveBigIntegerField()), - ], - options={ - 'verbose_name': 'L2VPN termination', - 'verbose_name_plural': 'L2VPN terminations', - 'ordering': ('l2vpn',), - }, - ), - migrations.CreateModel( - name='Prefix', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('prefix', ipam.fields.IPNetworkField()), - ('status', models.CharField(default='active', max_length=50)), - ('is_pool', models.BooleanField(default=False)), - ('mark_utilized', models.BooleanField(default=False)), - ('_depth', models.PositiveSmallIntegerField(default=0, editable=False)), - ('_children', models.PositiveBigIntegerField(default=0, editable=False)), - ], - options={ - 'verbose_name': 'prefix', - 'verbose_name_plural': 'prefixes', - 'ordering': (models.OrderBy(models.F('vrf'), nulls_first=True), 'prefix', 'pk'), - }, - bases=(ipam.models.ip.GetAvailablePrefixesMixin, models.Model), - ), - migrations.CreateModel( - name='RIR', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=100, unique=True)), - ('slug', models.SlugField(max_length=100, unique=True)), - ('description', models.CharField(blank=True, max_length=200)), - ('is_private', models.BooleanField(default=False)), - ], - options={ - 'verbose_name': 'RIR', - 'verbose_name_plural': 'RIRs', - 'ordering': ('name',), - }, - ), - migrations.CreateModel( - name='Role', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=100, unique=True)), - ('slug', models.SlugField(max_length=100, unique=True)), - ('description', models.CharField(blank=True, max_length=200)), - ('weight', models.PositiveSmallIntegerField(default=1000)), - ], - options={ - 'verbose_name': 'role', - 'verbose_name_plural': 'roles', - 'ordering': ('weight', 'name'), - }, - ), - migrations.CreateModel( - name='RouteTarget', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('name', models.CharField(max_length=21, unique=True)), - ], - options={ - 'verbose_name': 'route target', - 'verbose_name_plural': 'route targets', - 'ordering': ['name'], - }, - ), - migrations.CreateModel( - name='Service', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('protocol', models.CharField(max_length=50)), - ('ports', django.contrib.postgres.fields.ArrayField(base_field=models.PositiveIntegerField(validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(65535)]), size=None)), - ('name', models.CharField(max_length=100)), - ], - options={ - 'verbose_name': 'service', - 'verbose_name_plural': 'services', - 'ordering': ('protocol', 'ports', 'pk'), - }, - ), - migrations.CreateModel( - name='ServiceTemplate', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('protocol', models.CharField(max_length=50)), - ('ports', django.contrib.postgres.fields.ArrayField(base_field=models.PositiveIntegerField(validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(65535)]), size=None)), - ('name', models.CharField(max_length=100, unique=True)), - ], - options={ - 'verbose_name': 'service template', - 'verbose_name_plural': 'service templates', - 'ordering': ('name',), - }, - ), - migrations.CreateModel( - name='VLAN', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('vid', models.PositiveSmallIntegerField(validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(4094)])), - ('name', models.CharField(max_length=64)), - ('status', models.CharField(default='active', max_length=50)), - ], - options={ - 'verbose_name': 'VLAN', - 'verbose_name_plural': 'VLANs', - 'ordering': ('site', 'group', 'vid', 'pk'), - }, - ), - migrations.CreateModel( - name='VLANGroup', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('name', models.CharField(max_length=100)), - ('slug', models.SlugField(max_length=100)), - ('scope_id', models.PositiveBigIntegerField(blank=True, null=True)), - ('min_vid', models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(4094)])), - ('max_vid', models.PositiveSmallIntegerField(default=4094, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(4094)])), - ], - options={ - 'verbose_name': 'VLAN group', - 'verbose_name_plural': 'VLAN groups', - 'ordering': ('name', 'pk'), - }, - ), - migrations.CreateModel( - name='VRF', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('name', models.CharField(max_length=100)), - ('rd', models.CharField(blank=True, max_length=21, null=True, unique=True)), - ('enforce_unique', models.BooleanField(default=True)), - ('export_targets', models.ManyToManyField(blank=True, related_name='exporting_vrfs', to='ipam.routetarget')), - ('import_targets', models.ManyToManyField(blank=True, related_name='importing_vrfs', to='ipam.routetarget')), - ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), - ], - options={ - 'verbose_name': 'VRF', - 'verbose_name_plural': 'VRFs', - 'ordering': ('name', 'rd', 'pk'), - }, - ), - ] diff --git a/netbox/ipam/migrations/0001_squashed.py b/netbox/ipam/migrations/0001_squashed.py new file mode 100644 index 000000000..bef36e698 --- /dev/null +++ b/netbox/ipam/migrations/0001_squashed.py @@ -0,0 +1,210 @@ +import django.contrib.postgres.fields +from utilities.json import CustomFieldJSONEncoder +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion +import django.db.models.expressions +import ipam.fields +import taggit.managers + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('dcim', '0002_auto_20160622_1821'), + ('extras', '0001_initial'), + ('tenancy', '0001_initial'), + ] + + replaces = [ + ('ipam', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Aggregate', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('prefix', ipam.fields.IPNetworkField()), + ('date_added', models.DateField(blank=True, null=True)), + ('description', models.CharField(blank=True, max_length=200)), + ], + options={ + 'ordering': ('prefix', 'pk'), + }, + ), + migrations.CreateModel( + name='IPAddress', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('address', ipam.fields.IPAddressField()), + ('status', models.CharField(default='active', max_length=50)), + ('role', models.CharField(blank=True, max_length=50)), + ('assigned_object_id', models.PositiveIntegerField(blank=True, null=True)), + ('dns_name', models.CharField(blank=True, max_length=255, validators=[django.core.validators.RegexValidator(code='invalid', message='Only alphanumeric characters, asterisks, hyphens, periods, and underscores are allowed in DNS names', regex='^([0-9A-Za-z_-]+|\\*)(\\.[0-9A-Za-z_-]+)*\\.?$')])), + ('description', models.CharField(blank=True, max_length=200)), + ], + options={ + 'verbose_name': 'IP address', + 'verbose_name_plural': 'IP addresses', + 'ordering': ('address', 'pk'), + }, + ), + migrations.CreateModel( + name='Prefix', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('prefix', ipam.fields.IPNetworkField()), + ('status', models.CharField(default='active', max_length=50)), + ('is_pool', models.BooleanField(default=False)), + ('description', models.CharField(blank=True, max_length=200)), + ], + options={ + 'verbose_name_plural': 'prefixes', + 'ordering': (django.db.models.expressions.OrderBy(django.db.models.expressions.F('vrf'), nulls_first=True), 'prefix', 'pk'), + }, + ), + migrations.CreateModel( + name='RIR', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, unique=True)), + ('slug', models.SlugField(max_length=100, unique=True)), + ('is_private', models.BooleanField(default=False)), + ('description', models.CharField(blank=True, max_length=200)), + ], + options={ + 'verbose_name': 'RIR', + 'verbose_name_plural': 'RIRs', + 'ordering': ('name',), + }, + ), + migrations.CreateModel( + name='Role', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, unique=True)), + ('slug', models.SlugField(max_length=100, unique=True)), + ('weight', models.PositiveSmallIntegerField(default=1000)), + ('description', models.CharField(blank=True, max_length=200)), + ], + options={ + 'ordering': ('weight', 'name'), + }, + ), + migrations.CreateModel( + name='RouteTarget', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=21, unique=True)), + ('description', models.CharField(blank=True, max_length=200)), + ], + options={ + 'ordering': ['name'], + }, + ), + migrations.CreateModel( + name='VRF', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100)), + ('rd', models.CharField(blank=True, max_length=21, null=True, unique=True)), + ('enforce_unique', models.BooleanField(default=True)), + ('description', models.CharField(blank=True, max_length=200)), + ('export_targets', models.ManyToManyField(blank=True, related_name='exporting_vrfs', to='ipam.RouteTarget')), + ('import_targets', models.ManyToManyField(blank=True, related_name='importing_vrfs', to='ipam.RouteTarget')), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ('tenant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vrfs', to='tenancy.tenant')), + ], + options={ + 'verbose_name': 'VRF', + 'verbose_name_plural': 'VRFs', + 'ordering': ('name', 'rd', 'pk'), + }, + ), + migrations.CreateModel( + name='VLANGroup', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100)), + ('slug', models.SlugField(max_length=100)), + ('scope_id', models.PositiveBigIntegerField(blank=True, null=True)), + ('description', models.CharField(blank=True, max_length=200)), + ('scope_type', models.ForeignKey(blank=True, limit_choices_to=models.Q(('model__in', ('region', 'sitegroup', 'site', 'location', 'rack', 'clustergroup', 'cluster'))), null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')), + ], + options={ + 'verbose_name': 'VLAN group', + 'verbose_name_plural': 'VLAN groups', + 'ordering': ('name', 'pk'), + }, + ), + migrations.CreateModel( + name='VLAN', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('vid', models.PositiveSmallIntegerField(validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(4094)])), + ('name', models.CharField(max_length=64)), + ('status', models.CharField(default='active', max_length=50)), + ('description', models.CharField(blank=True, max_length=200)), + ('group', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vlans', to='ipam.vlangroup')), + ('role', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='vlans', to='ipam.role')), + ('site', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vlans', to='dcim.site')), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ('tenant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vlans', to='tenancy.tenant')), + ], + options={ + 'verbose_name': 'VLAN', + 'verbose_name_plural': 'VLANs', + 'ordering': ('site', 'group', 'vid', 'pk'), + }, + ), + migrations.CreateModel( + name='Service', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100)), + ('protocol', models.CharField(max_length=50)), + ('ports', django.contrib.postgres.fields.ArrayField(base_field=models.PositiveIntegerField(validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(65535)]), size=None)), + ('description', models.CharField(blank=True, max_length=200)), + ('device', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='services', to='dcim.device')), + ('ipaddresses', models.ManyToManyField(blank=True, related_name='services', to='ipam.IPAddress')), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ], + options={ + 'ordering': ('protocol', 'ports', 'pk'), + }, + ), + ] diff --git a/netbox/ipam/migrations/0002_squashed.py b/netbox/ipam/migrations/0002_squashed.py deleted file mode 100644 index 45ba1f1c9..000000000 --- a/netbox/ipam/migrations/0002_squashed.py +++ /dev/null @@ -1,375 +0,0 @@ -from django.db import migrations, models -import django.db.models.deletion -import django.db.models.functions.comparison -import ipam.fields -import ipam.lookups -import taggit.managers - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ('virtualization', '0001_initial'), - ('contenttypes', '0002_remove_content_type_name'), - ('extras', '0002_squashed'), - ('dcim', '0003_squashed'), - ('ipam', '0001_initial'), - ('tenancy', '0001_initial'), - ] - - replaces = [ - ('ipam', '0002_vrf_add_enforce_unique'), - ('ipam', '0003_ipam_add_vlangroups'), - ('ipam', '0004_ipam_vlangroup_uniqueness'), - ('ipam', '0005_auto_20160725_1842'), - ('ipam', '0006_vrf_vlan_add_tenant'), - ('ipam', '0007_prefix_ipaddress_add_tenant'), - ('ipam', '0008_prefix_change_order'), - ('ipam', '0009_ipaddress_add_status'), - ('ipam', '0010_ipaddress_help_texts'), - ('ipam', '0011_rir_add_is_private'), - ('ipam', '0012_services'), - ('ipam', '0013_prefix_add_is_pool'), - ('ipam', '0014_ipaddress_status_add_deprecated'), - ('ipam', '0015_global_vlans'), - ('ipam', '0016_unicode_literals'), - ('ipam', '0017_ipaddress_roles'), - ('ipam', '0018_remove_service_uniqueness_constraint'), - ('ipam', '0019_virtualization'), - ('ipam', '0020_ipaddress_add_role_carp'), - ('ipam', '0021_vrf_ordering'), - ('ipam', '0022_tags'), - ('ipam', '0023_change_logging'), - ('ipam', '0024_vrf_allow_null_rd'), - ('ipam', '0025_custom_tag_models'), - ('ipam', '0026_prefix_ordering_vrf_nulls_first'), - ('ipam', '0027_ipaddress_add_dns_name'), - ('ipam', '0028_3569_prefix_fields'), - ('ipam', '0029_3569_ipaddress_fields'), - ('ipam', '0030_3569_vlan_fields'), - ('ipam', '0031_3569_service_fields'), - ('ipam', '0032_role_description'), - ('ipam', '0033_deterministic_ordering'), - ('ipam', '0034_fix_ipaddress_status_dhcp'), - ('ipam', '0035_drop_ip_family'), - ('ipam', '0036_standardize_description'), - ('ipam', '0037_ipaddress_assignment'), - ('ipam', '0038_custom_field_data'), - ('ipam', '0039_service_ports_array'), - ('ipam', '0040_service_drop_port'), - ('ipam', '0041_routetarget'), - ('ipam', '0042_standardize_name_length'), - ('ipam', '0043_add_tenancy_to_aggregates'), - ('ipam', '0044_standardize_models'), - ('ipam', '0045_vlangroup_scope'), - ('ipam', '0046_set_vlangroup_scope_types'), - ('ipam', '0047_prefix_depth_children'), - ('ipam', '0048_prefix_populate_depth_children'), - ('ipam', '0049_prefix_mark_utilized'), - ('ipam', '0050_iprange'), - ('ipam', '0051_extend_tag_support'), - ('ipam', '0052_fhrpgroup'), - ('ipam', '0053_asn_model'), - ('ipam', '0054_vlangroup_min_max_vids'), - ('ipam', '0055_servicetemplate'), - ('ipam', '0056_standardize_id_fields'), - ('ipam', '0057_created_datetimefield'), - ('ipam', '0058_ipaddress_nat_inside_nonunique'), - ('ipam', '0059_l2vpn'), - ('ipam', '0060_alter_l2vpn_slug'), - ('ipam', '0061_fhrpgroup_name'), - ('ipam', '0062_unique_constraints'), - ('ipam', '0063_standardize_description_comments'), - ('ipam', '0064_clear_search_cache'), - ('ipam', '0065_asnrange'), - ('ipam', '0066_iprange_mark_utilized'), - ('ipam', '0067_ipaddress_index_host'), - ] - - operations = [ - migrations.AddField( - model_name='vrf', - name='tenant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vrfs', to='tenancy.tenant'), - ), - migrations.AddField( - model_name='vlangroup', - name='scope_type', - field=models.ForeignKey(blank=True, limit_choices_to=models.Q(('model__in', ('region', 'sitegroup', 'site', 'location', 'rack', 'clustergroup', 'cluster'))), null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype'), - ), - migrations.AddField( - model_name='vlangroup', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='vlan', - name='group', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vlans', to='ipam.vlangroup'), - ), - migrations.AddField( - model_name='vlan', - name='role', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='vlans', to='ipam.role'), - ), - migrations.AddField( - model_name='vlan', - name='site', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vlans', to='dcim.site'), - ), - migrations.AddField( - model_name='vlan', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='vlan', - name='tenant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vlans', to='tenancy.tenant'), - ), - migrations.AddField( - model_name='servicetemplate', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='service', - name='device', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='services', to='dcim.device'), - ), - migrations.AddField( - model_name='service', - name='ipaddresses', - field=models.ManyToManyField(blank=True, related_name='services', to='ipam.ipaddress'), - ), - migrations.AddField( - model_name='service', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='service', - name='virtual_machine', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='services', to='virtualization.virtualmachine'), - ), - migrations.AddField( - model_name='routetarget', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='routetarget', - name='tenant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='route_targets', to='tenancy.tenant'), - ), - migrations.AddField( - model_name='role', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='rir', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='prefix', - name='role', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='prefixes', to='ipam.role'), - ), - migrations.AddField( - model_name='prefix', - name='site', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='prefixes', to='dcim.site'), - ), - migrations.AddField( - model_name='prefix', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='prefix', - name='tenant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='prefixes', to='tenancy.tenant'), - ), - migrations.AddField( - model_name='prefix', - name='vlan', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='prefixes', to='ipam.vlan'), - ), - migrations.AddField( - model_name='prefix', - name='vrf', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='prefixes', to='ipam.vrf'), - ), - migrations.AddField( - model_name='l2vpntermination', - name='assigned_object_type', - field=models.ForeignKey(limit_choices_to=models.Q(models.Q(models.Q(('app_label', 'dcim'), ('model', 'interface')), models.Q(('app_label', 'ipam'), ('model', 'vlan')), models.Q(('app_label', 'virtualization'), ('model', 'vminterface')), _connector='OR')), on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype'), - ), - migrations.AddField( - model_name='l2vpntermination', - name='l2vpn', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='terminations', to='ipam.l2vpn'), - ), - migrations.AddField( - model_name='l2vpntermination', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='l2vpn', - name='export_targets', - field=models.ManyToManyField(blank=True, related_name='exporting_l2vpns', to='ipam.routetarget'), - ), - migrations.AddField( - model_name='l2vpn', - name='import_targets', - field=models.ManyToManyField(blank=True, related_name='importing_l2vpns', to='ipam.routetarget'), - ), - migrations.AddField( - model_name='l2vpn', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='l2vpn', - name='tenant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='l2vpns', to='tenancy.tenant'), - ), - migrations.AddField( - model_name='iprange', - name='role', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='ip_ranges', to='ipam.role'), - ), - migrations.AddField( - model_name='iprange', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='iprange', - name='tenant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='ip_ranges', to='tenancy.tenant'), - ), - migrations.AddField( - model_name='iprange', - name='vrf', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='ip_ranges', to='ipam.vrf'), - ), - migrations.AddField( - model_name='ipaddress', - name='assigned_object_type', - field=models.ForeignKey(blank=True, limit_choices_to=models.Q(models.Q(models.Q(('app_label', 'dcim'), ('model', 'interface')), models.Q(('app_label', 'ipam'), ('model', 'fhrpgroup')), models.Q(('app_label', 'virtualization'), ('model', 'vminterface')), _connector='OR')), null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype'), - ), - migrations.AddField( - model_name='ipaddress', - name='nat_inside', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='nat_outside', to='ipam.ipaddress'), - ), - migrations.AddField( - model_name='ipaddress', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='ipaddress', - name='tenant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='ip_addresses', to='tenancy.tenant'), - ), - migrations.AddField( - model_name='ipaddress', - name='vrf', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='ip_addresses', to='ipam.vrf'), - ), - migrations.AddField( - model_name='fhrpgroupassignment', - name='group', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='ipam.fhrpgroup'), - ), - migrations.AddField( - model_name='fhrpgroupassignment', - name='interface_type', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype'), - ), - migrations.AddField( - model_name='fhrpgroup', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='asnrange', - name='rir', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='asn_ranges', to='ipam.rir'), - ), - migrations.AddField( - model_name='asnrange', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='asnrange', - name='tenant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='asn_ranges', to='tenancy.tenant'), - ), - migrations.AddField( - model_name='asn', - name='rir', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='asns', to='ipam.rir'), - ), - migrations.AddField( - model_name='asn', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='asn', - name='tenant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='asns', to='tenancy.tenant'), - ), - migrations.AddField( - model_name='aggregate', - name='rir', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='aggregates', to='ipam.rir'), - ), - migrations.AddField( - model_name='aggregate', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddField( - model_name='aggregate', - name='tenant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='aggregates', to='tenancy.tenant'), - ), - migrations.AddConstraint( - model_name='vlangroup', - constraint=models.UniqueConstraint(fields=('scope_type', 'scope_id', 'name'), name='ipam_vlangroup_unique_scope_name'), - ), - migrations.AddConstraint( - model_name='vlangroup', - constraint=models.UniqueConstraint(fields=('scope_type', 'scope_id', 'slug'), name='ipam_vlangroup_unique_scope_slug'), - ), - migrations.AddConstraint( - model_name='vlan', - constraint=models.UniqueConstraint(fields=('group', 'vid'), name='ipam_vlan_unique_group_vid'), - ), - migrations.AddConstraint( - model_name='vlan', - constraint=models.UniqueConstraint(fields=('group', 'name'), name='ipam_vlan_unique_group_name'), - ), - migrations.AddConstraint( - model_name='l2vpntermination', - constraint=models.UniqueConstraint(fields=('assigned_object_type', 'assigned_object_id'), name='ipam_l2vpntermination_assigned_object'), - ), - migrations.AddIndex( - model_name='ipaddress', - index=models.Index(django.db.models.functions.comparison.Cast(ipam.lookups.Host('address'), output_field=ipam.fields.IPAddressField()), name='ipam_ipaddress_host'), - ), - migrations.AddConstraint( - model_name='fhrpgroupassignment', - constraint=models.UniqueConstraint(fields=('interface_type', 'interface_id', 'group'), name='ipam_fhrpgroupassignment_unique_interface_group'), - ), - ] diff --git a/netbox/ipam/migrations/0002_squashed_0046.py b/netbox/ipam/migrations/0002_squashed_0046.py new file mode 100644 index 000000000..06bcd8741 --- /dev/null +++ b/netbox/ipam/migrations/0002_squashed_0046.py @@ -0,0 +1,159 @@ +from django.db import migrations, models +import django.db.models.deletion +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0003_auto_20160628_1721'), + ('virtualization', '0001_virtualization'), + ('contenttypes', '0002_remove_content_type_name'), + ('ipam', '0001_initial'), + ('extras', '0002_custom_fields'), + ('tenancy', '0001_initial'), + ] + + replaces = [ + ('ipam', '0002_vrf_add_enforce_unique'), + ('ipam', '0003_ipam_add_vlangroups'), + ('ipam', '0004_ipam_vlangroup_uniqueness'), + ('ipam', '0005_auto_20160725_1842'), + ('ipam', '0006_vrf_vlan_add_tenant'), + ('ipam', '0007_prefix_ipaddress_add_tenant'), + ('ipam', '0008_prefix_change_order'), + ('ipam', '0009_ipaddress_add_status'), + ('ipam', '0010_ipaddress_help_texts'), + ('ipam', '0011_rir_add_is_private'), + ('ipam', '0012_services'), + ('ipam', '0013_prefix_add_is_pool'), + ('ipam', '0014_ipaddress_status_add_deprecated'), + ('ipam', '0015_global_vlans'), + ('ipam', '0016_unicode_literals'), + ('ipam', '0017_ipaddress_roles'), + ('ipam', '0018_remove_service_uniqueness_constraint'), + ('ipam', '0019_virtualization'), + ('ipam', '0020_ipaddress_add_role_carp'), + ('ipam', '0021_vrf_ordering'), + ('ipam', '0022_tags'), + ('ipam', '0023_change_logging'), + ('ipam', '0024_vrf_allow_null_rd'), + ('ipam', '0025_custom_tag_models'), + ('ipam', '0026_prefix_ordering_vrf_nulls_first'), + ('ipam', '0027_ipaddress_add_dns_name'), + ('ipam', '0028_3569_prefix_fields'), + ('ipam', '0029_3569_ipaddress_fields'), + ('ipam', '0030_3569_vlan_fields'), + ('ipam', '0031_3569_service_fields'), + ('ipam', '0032_role_description'), + ('ipam', '0033_deterministic_ordering'), + ('ipam', '0034_fix_ipaddress_status_dhcp'), + ('ipam', '0035_drop_ip_family'), + ('ipam', '0036_standardize_description'), + ('ipam', '0037_ipaddress_assignment'), + ('ipam', '0038_custom_field_data'), + ('ipam', '0039_service_ports_array'), + ('ipam', '0040_service_drop_port'), + ('ipam', '0041_routetarget'), + ('ipam', '0042_standardize_name_length'), + ('ipam', '0043_add_tenancy_to_aggregates'), + ('ipam', '0044_standardize_models'), + ('ipam', '0045_vlangroup_scope'), + ('ipam', '0046_set_vlangroup_scope_types'), + ] + + operations = [ + migrations.AddField( + model_name='service', + name='virtual_machine', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='services', to='virtualization.virtualmachine'), + ), + migrations.AddField( + model_name='routetarget', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='routetarget', + name='tenant', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='route_targets', to='tenancy.tenant'), + ), + migrations.AddField( + model_name='prefix', + name='role', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='prefixes', to='ipam.role'), + ), + migrations.AddField( + model_name='prefix', + name='site', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='prefixes', to='dcim.site'), + ), + migrations.AddField( + model_name='prefix', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='prefix', + name='tenant', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='prefixes', to='tenancy.tenant'), + ), + migrations.AddField( + model_name='prefix', + name='vlan', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='prefixes', to='ipam.vlan'), + ), + migrations.AddField( + model_name='prefix', + name='vrf', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='prefixes', to='ipam.vrf'), + ), + migrations.AddField( + model_name='ipaddress', + name='assigned_object_type', + field=models.ForeignKey(blank=True, limit_choices_to=models.Q(models.Q(models.Q(('app_label', 'dcim'), ('model', 'interface')), models.Q(('app_label', 'virtualization'), ('model', 'vminterface')), _connector='OR')), null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype'), + ), + migrations.AddField( + model_name='ipaddress', + name='nat_inside', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='nat_outside', to='ipam.ipaddress'), + ), + migrations.AddField( + model_name='ipaddress', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='ipaddress', + name='tenant', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='ip_addresses', to='tenancy.tenant'), + ), + migrations.AddField( + model_name='ipaddress', + name='vrf', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='ip_addresses', to='ipam.vrf'), + ), + migrations.AddField( + model_name='aggregate', + name='rir', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='aggregates', to='ipam.rir'), + ), + migrations.AddField( + model_name='aggregate', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='aggregate', + name='tenant', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='aggregates', to='tenancy.tenant'), + ), + migrations.AlterUniqueTogether( + name='vlangroup', + unique_together={('scope_type', 'scope_id', 'name'), ('scope_type', 'scope_id', 'slug')}, + ), + migrations.AlterUniqueTogether( + name='vlan', + unique_together={('group', 'vid'), ('group', 'name')}, + ), + ] diff --git a/netbox/ipam/migrations/0047_prefix_depth_children.py b/netbox/ipam/migrations/0047_prefix_depth_children.py new file mode 100644 index 000000000..4c49b1358 --- /dev/null +++ b/netbox/ipam/migrations/0047_prefix_depth_children.py @@ -0,0 +1,21 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0046_set_vlangroup_scope_types'), + ] + + operations = [ + migrations.AddField( + model_name='prefix', + name='_children', + field=models.PositiveBigIntegerField(default=0, editable=False), + ), + migrations.AddField( + model_name='prefix', + name='_depth', + field=models.PositiveSmallIntegerField(default=0, editable=False), + ), + ] diff --git a/netbox/ipam/migrations/0048_prefix_populate_depth_children.py b/netbox/ipam/migrations/0048_prefix_populate_depth_children.py new file mode 100644 index 000000000..5ec448ee1 --- /dev/null +++ b/netbox/ipam/migrations/0048_prefix_populate_depth_children.py @@ -0,0 +1,37 @@ +import sys +from django.db import migrations + +from ipam.utils import rebuild_prefixes + + +def populate_prefix_hierarchy(apps, schema_editor): + """ + Populate _depth and _children attrs for all Prefixes. + """ + Prefix = apps.get_model('ipam', 'Prefix') + VRF = apps.get_model('ipam', 'VRF') + + total_count = Prefix.objects.count() + if 'test' not in sys.argv: + print(f'\nUpdating {total_count} prefixes...') + + # Rebuild the global table + rebuild_prefixes(None) + + # Iterate through all VRFs, rebuilding each + for vrf in VRF.objects.all(): + rebuild_prefixes(vrf.pk) + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0047_prefix_depth_children'), + ] + + operations = [ + migrations.RunPython( + code=populate_prefix_hierarchy, + reverse_code=migrations.RunPython.noop + ), + ] diff --git a/netbox/ipam/migrations/0049_prefix_mark_utilized.py b/netbox/ipam/migrations/0049_prefix_mark_utilized.py new file mode 100644 index 000000000..4274d92a0 --- /dev/null +++ b/netbox/ipam/migrations/0049_prefix_mark_utilized.py @@ -0,0 +1,16 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0048_prefix_populate_depth_children'), + ] + + operations = [ + migrations.AddField( + model_name='prefix', + name='mark_utilized', + field=models.BooleanField(default=False), + ), + ] diff --git a/netbox/ipam/migrations/0050_iprange.py b/netbox/ipam/migrations/0050_iprange.py new file mode 100644 index 000000000..374b2547c --- /dev/null +++ b/netbox/ipam/migrations/0050_iprange.py @@ -0,0 +1,43 @@ +# Generated by Django 3.2.5 on 2021-07-16 14:15 + +from utilities.json import CustomFieldJSONEncoder +from django.db import migrations, models +import django.db.models.deletion +import django.db.models.expressions +import ipam.fields +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0061_extras_change_logging'), + ('tenancy', '0001_squashed_0012'), + ('ipam', '0049_prefix_mark_utilized'), + ] + + operations = [ + migrations.CreateModel( + name='IPRange', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('start_address', ipam.fields.IPAddressField()), + ('end_address', ipam.fields.IPAddressField()), + ('size', models.PositiveIntegerField(editable=False)), + ('status', models.CharField(default='active', max_length=50)), + ('description', models.CharField(blank=True, max_length=200)), + ('role', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='ip_ranges', to='ipam.role')), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ('tenant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='ip_ranges', to='tenancy.tenant')), + ('vrf', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='ip_ranges', to='ipam.vrf')), + ], + options={ + 'verbose_name': 'IP range', + 'verbose_name_plural': 'IP ranges', + 'ordering': (django.db.models.expressions.OrderBy(django.db.models.expressions.F('vrf'), nulls_first=True), 'start_address', 'pk'), + }, + ), + ] diff --git a/netbox/circuits/migrations/0002_squashed.py b/netbox/ipam/migrations/0051_extend_tag_support.py similarity index 51% rename from netbox/circuits/migrations/0002_squashed.py rename to netbox/ipam/migrations/0051_extend_tag_support.py index 3bb7f9580..ea31a6645 100644 --- a/netbox/circuits/migrations/0002_squashed.py +++ b/netbox/ipam/migrations/0051_extend_tag_support.py @@ -1,30 +1,29 @@ -from django.db import migrations, models -import django.db.models.deletion +# Generated by Django 3.2.8 on 2021-10-21 14:50 + +from django.db import migrations import taggit.managers class Migration(migrations.Migration): - initial = True - dependencies = [ - ('extras', '0001_initial'), - ('circuits', '0001_initial'), + ('extras', '0062_clear_secrets_changelog'), + ('ipam', '0050_iprange'), ] operations = [ migrations.AddField( - model_name='providernetwork', + model_name='rir', name='tags', field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), ), migrations.AddField( - model_name='provideraccount', - name='provider', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='accounts', to='circuits.provider'), + model_name='role', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), ), migrations.AddField( - model_name='provideraccount', + model_name='vlangroup', name='tags', field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), ), diff --git a/netbox/ipam/migrations/0052_fhrpgroup.py b/netbox/ipam/migrations/0052_fhrpgroup.py new file mode 100644 index 000000000..e69e49d48 --- /dev/null +++ b/netbox/ipam/migrations/0052_fhrpgroup.py @@ -0,0 +1,58 @@ +from utilities.json import CustomFieldJSONEncoder +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('extras', '0064_configrevision'), + ('ipam', '0051_extend_tag_support'), + ] + + operations = [ + migrations.CreateModel( + name='FHRPGroup', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('group_id', models.PositiveSmallIntegerField()), + ('protocol', models.CharField(max_length=50)), + ('auth_type', models.CharField(blank=True, max_length=50)), + ('auth_key', models.CharField(blank=True, max_length=255)), + ('description', models.CharField(blank=True, max_length=200)), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ], + options={ + 'verbose_name': 'FHRP group', + 'ordering': ['protocol', 'group_id', 'pk'], + }, + ), + migrations.AlterField( + model_name='ipaddress', + name='assigned_object_type', + field=models.ForeignKey(blank=True, limit_choices_to=models.Q(models.Q(models.Q(('app_label', 'dcim'), ('model', 'interface')), models.Q(('app_label', 'ipam'), ('model', 'fhrpgroup')), models.Q(('app_label', 'virtualization'), ('model', 'vminterface')), _connector='OR')), null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype'), + ), + migrations.CreateModel( + name='FHRPGroupAssignment', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('interface_id', models.PositiveIntegerField()), + ('priority', models.PositiveSmallIntegerField(validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(255)])), + ('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='ipam.fhrpgroup')), + ('interface_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')), + ], + options={ + 'verbose_name': 'FHRP group assignment', + 'ordering': ('-priority', 'pk'), + 'unique_together': {('interface_type', 'interface_id', 'group')}, + }, + ), + ] diff --git a/netbox/ipam/migrations/0053_asn_model.py b/netbox/ipam/migrations/0053_asn_model.py new file mode 100644 index 000000000..99bde12e6 --- /dev/null +++ b/netbox/ipam/migrations/0053_asn_model.py @@ -0,0 +1,36 @@ +import ipam.fields +from utilities.json import CustomFieldJSONEncoder +from django.db import migrations, models +import django.db.models.deletion +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ('tenancy', '0004_extend_tag_support'), + ('extras', '0064_configrevision'), + ('ipam', '0052_fhrpgroup'), + ] + + operations = [ + migrations.CreateModel( + name='ASN', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('asn', ipam.fields.ASNField(unique=True)), + ('description', models.CharField(blank=True, max_length=200)), + ('rir', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='asns', to='ipam.rir')), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ('tenant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='asns', to='tenancy.tenant')), + ], + options={ + 'verbose_name': 'ASN', + 'verbose_name_plural': 'ASNs', + 'ordering': ['asn'], + }, + ), + ] diff --git a/netbox/ipam/migrations/0054_vlangroup_min_max_vids.py b/netbox/ipam/migrations/0054_vlangroup_min_max_vids.py new file mode 100644 index 000000000..7b901fe13 --- /dev/null +++ b/netbox/ipam/migrations/0054_vlangroup_min_max_vids.py @@ -0,0 +1,25 @@ +# Generated by Django 3.2.10 on 2021-12-23 15:24 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0145_site_remove_deprecated_fields'), + ('ipam', '0053_asn_model'), + ] + + operations = [ + migrations.AddField( + model_name='vlangroup', + name='max_vid', + field=models.PositiveSmallIntegerField(default=4094, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(4094)]), + ), + migrations.AddField( + model_name='vlangroup', + name='min_vid', + field=models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(4094)]), + ), + ] diff --git a/netbox/ipam/migrations/0055_servicetemplate.py b/netbox/ipam/migrations/0055_servicetemplate.py new file mode 100644 index 000000000..c8ba6645c --- /dev/null +++ b/netbox/ipam/migrations/0055_servicetemplate.py @@ -0,0 +1,33 @@ +import django.contrib.postgres.fields +from utilities.json import CustomFieldJSONEncoder +import django.core.validators +from django.db import migrations, models +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0070_customlink_enabled'), + ('ipam', '0054_vlangroup_min_max_vids'), + ] + + operations = [ + migrations.CreateModel( + name='ServiceTemplate', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('protocol', models.CharField(max_length=50)), + ('ports', django.contrib.postgres.fields.ArrayField(base_field=models.PositiveIntegerField(validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(65535)]), size=None)), + ('description', models.CharField(blank=True, max_length=200)), + ('name', models.CharField(max_length=100, unique=True)), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ], + options={ + 'ordering': ('name',), + }, + ), + ] diff --git a/netbox/ipam/migrations/0056_standardize_id_fields.py b/netbox/ipam/migrations/0056_standardize_id_fields.py new file mode 100644 index 000000000..cb7564450 --- /dev/null +++ b/netbox/ipam/migrations/0056_standardize_id_fields.py @@ -0,0 +1,99 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0055_servicetemplate'), + ] + + operations = [ + # Model IDs + migrations.AlterField( + model_name='aggregate', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='asn', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='fhrpgroup', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='fhrpgroupassignment', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='ipaddress', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='iprange', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='prefix', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='rir', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='role', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='routetarget', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='service', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='servicetemplate', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='vlan', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='vlangroup', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='vrf', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + + # GFK IDs + migrations.AlterField( + model_name='fhrpgroupassignment', + name='interface_id', + field=models.PositiveBigIntegerField(), + ), + migrations.AlterField( + model_name='ipaddress', + name='assigned_object_id', + field=models.PositiveBigIntegerField(blank=True, null=True), + ), + ] diff --git a/netbox/ipam/migrations/0057_created_datetimefield.py b/netbox/ipam/migrations/0057_created_datetimefield.py new file mode 100644 index 000000000..f2ca7ab95 --- /dev/null +++ b/netbox/ipam/migrations/0057_created_datetimefield.py @@ -0,0 +1,88 @@ +# Generated by Django 4.0.2 on 2022-02-08 18:54 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0056_standardize_id_fields'), + ] + + operations = [ + migrations.AlterField( + model_name='aggregate', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='asn', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='fhrpgroup', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='fhrpgroupassignment', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='ipaddress', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='iprange', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='prefix', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='rir', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='role', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='routetarget', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='service', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='servicetemplate', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='vlan', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='vlangroup', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='vrf', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + ] diff --git a/netbox/ipam/migrations/0058_ipaddress_nat_inside_nonunique.py b/netbox/ipam/migrations/0058_ipaddress_nat_inside_nonunique.py new file mode 100644 index 000000000..63e93d137 --- /dev/null +++ b/netbox/ipam/migrations/0058_ipaddress_nat_inside_nonunique.py @@ -0,0 +1,17 @@ +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0057_created_datetimefield'), + ] + + operations = [ + migrations.AlterField( + model_name='ipaddress', + name='nat_inside', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='nat_outside', to='ipam.ipaddress'), + ), + ] diff --git a/netbox/ipam/migrations/0059_l2vpn.py b/netbox/ipam/migrations/0059_l2vpn.py new file mode 100644 index 000000000..59dbab632 --- /dev/null +++ b/netbox/ipam/migrations/0059_l2vpn.py @@ -0,0 +1,60 @@ +from utilities.json import CustomFieldJSONEncoder +from django.db import migrations, models +import django.db.models.deletion +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0075_configcontext_locations'), + ('contenttypes', '0002_remove_content_type_name'), + ('tenancy', '0007_contact_link'), + ('ipam', '0058_ipaddress_nat_inside_nonunique'), + ] + + operations = [ + migrations.CreateModel( + name='L2VPN', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('name', models.CharField(max_length=100, unique=True)), + ('slug', models.SlugField()), + ('type', models.CharField(max_length=50)), + ('identifier', models.BigIntegerField(blank=True, null=True)), + ('description', models.CharField(blank=True, max_length=200)), + ('export_targets', models.ManyToManyField(blank=True, related_name='exporting_l2vpns', to='ipam.routetarget')), + ('import_targets', models.ManyToManyField(blank=True, related_name='importing_l2vpns', to='ipam.routetarget')), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ('tenant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='l2vpns', to='tenancy.tenant')), + ], + options={ + 'verbose_name': 'L2VPN', + 'ordering': ('name', 'identifier'), + }, + ), + migrations.CreateModel( + name='L2VPNTermination', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('assigned_object_id', models.PositiveBigIntegerField()), + ('assigned_object_type', models.ForeignKey(limit_choices_to=models.Q(models.Q(models.Q(('app_label', 'dcim'), ('model', 'interface')), models.Q(('app_label', 'ipam'), ('model', 'vlan')), models.Q(('app_label', 'virtualization'), ('model', 'vminterface')), _connector='OR')), on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype')), + ('l2vpn', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='terminations', to='ipam.l2vpn')), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ], + options={ + 'verbose_name': 'L2VPN termination', + 'ordering': ('l2vpn',), + }, + ), + migrations.AddConstraint( + model_name='l2vpntermination', + constraint=models.UniqueConstraint(fields=('assigned_object_type', 'assigned_object_id'), name='ipam_l2vpntermination_assigned_object'), + ), + ] diff --git a/netbox/ipam/migrations/0060_alter_l2vpn_slug.py b/netbox/ipam/migrations/0060_alter_l2vpn_slug.py new file mode 100644 index 000000000..9e70c2063 --- /dev/null +++ b/netbox/ipam/migrations/0060_alter_l2vpn_slug.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0.7 on 2022-08-22 15:58 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0059_l2vpn'), + ] + + operations = [ + migrations.AlterField( + model_name='l2vpn', + name='slug', + field=models.SlugField(max_length=100, unique=True), + ), + ] diff --git a/netbox/ipam/migrations/0061_fhrpgroup_name.py b/netbox/ipam/migrations/0061_fhrpgroup_name.py new file mode 100644 index 000000000..7e232c18f --- /dev/null +++ b/netbox/ipam/migrations/0061_fhrpgroup_name.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0.7 on 2022-09-20 23:03 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0060_alter_l2vpn_slug'), + ] + + operations = [ + migrations.AddField( + model_name='fhrpgroup', + name='name', + field=models.CharField(blank=True, max_length=100), + ), + ] diff --git a/netbox/ipam/migrations/0062_unique_constraints.py b/netbox/ipam/migrations/0062_unique_constraints.py new file mode 100644 index 000000000..47c1a1214 --- /dev/null +++ b/netbox/ipam/migrations/0062_unique_constraints.py @@ -0,0 +1,43 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0061_fhrpgroup_name'), + ] + + operations = [ + migrations.AlterUniqueTogether( + name='fhrpgroupassignment', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='vlan', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='vlangroup', + unique_together=set(), + ), + migrations.AddConstraint( + model_name='fhrpgroupassignment', + constraint=models.UniqueConstraint(fields=('interface_type', 'interface_id', 'group'), name='ipam_fhrpgroupassignment_unique_interface_group'), + ), + migrations.AddConstraint( + model_name='vlan', + constraint=models.UniqueConstraint(fields=('group', 'vid'), name='ipam_vlan_unique_group_vid'), + ), + migrations.AddConstraint( + model_name='vlan', + constraint=models.UniqueConstraint(fields=('group', 'name'), name='ipam_vlan_unique_group_name'), + ), + migrations.AddConstraint( + model_name='vlangroup', + constraint=models.UniqueConstraint(fields=('scope_type', 'scope_id', 'name'), name='ipam_vlangroup_unique_scope_name'), + ), + migrations.AddConstraint( + model_name='vlangroup', + constraint=models.UniqueConstraint(fields=('scope_type', 'scope_id', 'slug'), name='ipam_vlangroup_unique_scope_slug'), + ), + ] diff --git a/netbox/ipam/migrations/0063_standardize_description_comments.py b/netbox/ipam/migrations/0063_standardize_description_comments.py new file mode 100644 index 000000000..3a4959d14 --- /dev/null +++ b/netbox/ipam/migrations/0063_standardize_description_comments.py @@ -0,0 +1,73 @@ +# Generated by Django 4.1.2 on 2022-11-03 18:24 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0062_unique_constraints'), + ] + + operations = [ + migrations.AddField( + model_name='aggregate', + name='comments', + field=models.TextField(blank=True), + ), + migrations.AddField( + model_name='asn', + name='comments', + field=models.TextField(blank=True), + ), + migrations.AddField( + model_name='fhrpgroup', + name='comments', + field=models.TextField(blank=True), + ), + migrations.AddField( + model_name='ipaddress', + name='comments', + field=models.TextField(blank=True), + ), + migrations.AddField( + model_name='iprange', + name='comments', + field=models.TextField(blank=True), + ), + migrations.AddField( + model_name='l2vpn', + name='comments', + field=models.TextField(blank=True), + ), + migrations.AddField( + model_name='prefix', + name='comments', + field=models.TextField(blank=True), + ), + migrations.AddField( + model_name='routetarget', + name='comments', + field=models.TextField(blank=True), + ), + migrations.AddField( + model_name='service', + name='comments', + field=models.TextField(blank=True), + ), + migrations.AddField( + model_name='servicetemplate', + name='comments', + field=models.TextField(blank=True), + ), + migrations.AddField( + model_name='vlan', + name='comments', + field=models.TextField(blank=True), + ), + migrations.AddField( + model_name='vrf', + name='comments', + field=models.TextField(blank=True), + ), + ] diff --git a/netbox/ipam/migrations/0064_clear_search_cache.py b/netbox/ipam/migrations/0064_clear_search_cache.py new file mode 100644 index 000000000..856fe99e1 --- /dev/null +++ b/netbox/ipam/migrations/0064_clear_search_cache.py @@ -0,0 +1,31 @@ +from django.db import migrations + + +def clear_cache(apps, schema_editor): + """ + Clear existing CachedValues referencing IPAddressFields or IPNetworkFields. (#11658 + introduced new cache record types for these.) + """ + ContentType = apps.get_model('contenttypes', 'ContentType') + CachedValue = apps.get_model('extras', 'CachedValue') + + for model_name in ('Aggregate', 'IPAddress', 'IPRange', 'Prefix'): + try: + content_type = ContentType.objects.get(app_label='ipam', model=model_name.lower()) + CachedValue.objects.filter(object_type=content_type).delete() + except ContentType.DoesNotExist: + pass + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0063_standardize_description_comments'), + ] + + operations = [ + migrations.RunPython( + code=clear_cache, + reverse_code=migrations.RunPython.noop + ), + ] diff --git a/netbox/ipam/migrations/0065_asnrange.py b/netbox/ipam/migrations/0065_asnrange.py new file mode 100644 index 000000000..71d056dfd --- /dev/null +++ b/netbox/ipam/migrations/0065_asnrange.py @@ -0,0 +1,41 @@ +# Generated by Django 4.1.7 on 2023-02-26 19:33 + +from django.db import migrations, models +import django.db.models.deletion +import ipam.fields +import taggit.managers +import utilities.json + + +class Migration(migrations.Migration): + + dependencies = [ + ('tenancy', '0009_standardize_description_comments'), + ('extras', '0087_dashboard'), + ('ipam', '0064_clear_search_cache'), + ] + + operations = [ + migrations.CreateModel( + name='ASNRange', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), + ('description', models.CharField(blank=True, max_length=200)), + ('name', models.CharField(max_length=100, unique=True)), + ('slug', models.SlugField(max_length=100, unique=True)), + ('start', ipam.fields.ASNField()), + ('end', ipam.fields.ASNField()), + ('rir', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='asn_ranges', to='ipam.rir')), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ('tenant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='asn_ranges', to='tenancy.tenant')), + ], + options={ + 'verbose_name': 'ASN range', + 'verbose_name_plural': 'ASN ranges', + 'ordering': ('name',), + }, + ), + ] diff --git a/netbox/ipam/migrations/0066_iprange_mark_utilized.py b/netbox/ipam/migrations/0066_iprange_mark_utilized.py new file mode 100644 index 000000000..2489289fd --- /dev/null +++ b/netbox/ipam/migrations/0066_iprange_mark_utilized.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.7 on 2023-02-28 14:51 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0065_asnrange'), + ] + + operations = [ + migrations.AddField( + model_name='iprange', + name='mark_utilized', + field=models.BooleanField(default=False), + ), + ] diff --git a/netbox/ipam/migrations/0067_ipaddress_index_host.py b/netbox/ipam/migrations/0067_ipaddress_index_host.py new file mode 100644 index 000000000..2383fd9aa --- /dev/null +++ b/netbox/ipam/migrations/0067_ipaddress_index_host.py @@ -0,0 +1,20 @@ +# Generated by Django 4.1.10 on 2023-08-02 12:43 + +from django.db import migrations, models +import django.db.models.functions.comparison +import ipam.fields +import ipam.lookups + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0066_iprange_mark_utilized'), + ] + + operations = [ + migrations.AddIndex( + model_name='ipaddress', + index=models.Index(django.db.models.functions.comparison.Cast(ipam.lookups.Host('address'), output_field=ipam.fields.IPAddressField()), name='ipam_ipaddress_host'), + ), + ] diff --git a/netbox/tenancy/migrations/0001_initial.py b/netbox/tenancy/migrations/0001_initial.py deleted file mode 100644 index 425899807..000000000 --- a/netbox/tenancy/migrations/0001_initial.py +++ /dev/null @@ -1,208 +0,0 @@ -from django.db import migrations, models -import django.db.models.deletion -import mptt.fields -import taggit.managers -import utilities.json - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ('extras', '0001_initial'), - ('contenttypes', '0002_remove_content_type_name'), - ] - - replaces = [ - # Squashed for v3.0 - ('tenancy', '0002_tenant_group_optional'), - ('tenancy', '0003_unicode_literals'), - ('tenancy', '0004_tags'), - ('tenancy', '0005_change_logging'), - ('tenancy', '0006_custom_tag_models'), - ('tenancy', '0007_nested_tenantgroups'), - ('tenancy', '0008_nested_tenantgroups_rebuild'), - ('tenancy', '0009_standardize_description'), - ('tenancy', '0010_custom_field_data'), - ('tenancy', '0011_standardize_name_length'), - ('tenancy', '0012_standardize_models'), - - # Squashed for v4.0 - ('tenancy', '0002_tenant_ordering'), - ('tenancy', '0003_contacts'), - ('tenancy', '0004_extend_tag_support'), - ('tenancy', '0005_standardize_id_fields'), - ('tenancy', '0006_created_datetimefield'), - ('tenancy', '0007_contact_link'), - ('tenancy', '0008_unique_constraints'), - ('tenancy', '0009_standardize_description_comments'), - ('tenancy', '0010_tenant_relax_uniqueness'), - ('tenancy', '0011_contactassignment_tags'), - ] - - operations = [ - migrations.CreateModel( - name='Contact', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('name', models.CharField(max_length=100)), - ('title', models.CharField(blank=True, max_length=100)), - ('phone', models.CharField(blank=True, max_length=50)), - ('email', models.EmailField(blank=True, max_length=254)), - ('address', models.CharField(blank=True, max_length=200)), - ('link', models.URLField(blank=True)), - ], - options={ - 'verbose_name': 'contact', - 'verbose_name_plural': 'contacts', - 'ordering': ['name'], - }, - ), - migrations.CreateModel( - name='TenantGroup', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('name', models.CharField(max_length=100, unique=True)), - ('slug', models.SlugField(max_length=100, unique=True)), - ('lft', models.PositiveIntegerField(editable=False)), - ('rght', models.PositiveIntegerField(editable=False)), - ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), - ('level', models.PositiveIntegerField(editable=False)), - ('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='tenancy.tenantgroup')), - ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), - ], - options={ - 'verbose_name': 'tenant group', - 'verbose_name_plural': 'tenant groups', - 'ordering': ['name'], - }, - ), - migrations.CreateModel( - name='Tenant', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('name', models.CharField(max_length=100)), - ('slug', models.SlugField(max_length=100)), - ('group', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='tenants', to='tenancy.tenantgroup')), - ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), - ], - options={ - 'verbose_name': 'tenant', - 'verbose_name_plural': 'tenants', - 'ordering': ['name'], - }, - ), - migrations.CreateModel( - name='ContactRole', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=100, unique=True)), - ('slug', models.SlugField(max_length=100, unique=True)), - ('description', models.CharField(blank=True, max_length=200)), - ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), - ], - options={ - 'verbose_name': 'contact role', - 'verbose_name_plural': 'contact roles', - 'ordering': ('name',), - }, - ), - migrations.CreateModel( - name='ContactGroup', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('name', models.CharField(max_length=100)), - ('slug', models.SlugField(max_length=100)), - ('description', models.CharField(blank=True, max_length=200)), - ('lft', models.PositiveIntegerField(editable=False)), - ('rght', models.PositiveIntegerField(editable=False)), - ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), - ('level', models.PositiveIntegerField(editable=False)), - ('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='tenancy.contactgroup')), - ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), - ], - options={ - 'verbose_name': 'contact group', - 'verbose_name_plural': 'contact groups', - 'ordering': ['name'], - }, - ), - migrations.CreateModel( - name='ContactAssignment', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('object_id', models.PositiveBigIntegerField()), - ('priority', models.CharField(blank=True, max_length=50)), - ('contact', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='assignments', to='tenancy.contact')), - ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')), - ('role', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='assignments', to='tenancy.contactrole')), - ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), - ], - options={ - 'verbose_name': 'contact assignment', - 'verbose_name_plural': 'contact assignments', - 'ordering': ('priority', 'contact'), - }, - ), - migrations.AddField( - model_name='contact', - name='group', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='contacts', to='tenancy.contactgroup'), - ), - migrations.AddField( - model_name='contact', - name='tags', - field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), - ), - migrations.AddConstraint( - model_name='tenant', - constraint=models.UniqueConstraint(fields=('group', 'name'), name='tenancy_tenant_unique_group_name', violation_error_message='Tenant name must be unique per group.'), - ), - migrations.AddConstraint( - model_name='tenant', - constraint=models.UniqueConstraint(condition=models.Q(('group__isnull', True)), fields=('name',), name='tenancy_tenant_unique_name'), - ), - migrations.AddConstraint( - model_name='tenant', - constraint=models.UniqueConstraint(fields=('group', 'slug'), name='tenancy_tenant_unique_group_slug', violation_error_message='Tenant slug must be unique per group.'), - ), - migrations.AddConstraint( - model_name='tenant', - constraint=models.UniqueConstraint(condition=models.Q(('group__isnull', True)), fields=('slug',), name='tenancy_tenant_unique_slug'), - ), - migrations.AddConstraint( - model_name='contactgroup', - constraint=models.UniqueConstraint(fields=('parent', 'name'), name='tenancy_contactgroup_unique_parent_name'), - ), - migrations.AddConstraint( - model_name='contactassignment', - constraint=models.UniqueConstraint(fields=('content_type', 'object_id', 'contact', 'role'), name='tenancy_contactassignment_unique_object_contact_role'), - ), - migrations.AddConstraint( - model_name='contact', - constraint=models.UniqueConstraint(fields=('group', 'name'), name='tenancy_contact_unique_group_name'), - ), - ] diff --git a/netbox/tenancy/migrations/0001_squashed_0012.py b/netbox/tenancy/migrations/0001_squashed_0012.py new file mode 100644 index 000000000..e8a028a92 --- /dev/null +++ b/netbox/tenancy/migrations/0001_squashed_0012.py @@ -0,0 +1,70 @@ +from utilities.json import CustomFieldJSONEncoder +from django.db import migrations, models +import django.db.models.deletion +import mptt.fields +import taggit.managers + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('extras', '0001_initial'), + ] + + replaces = [ + ('tenancy', '0001_initial'), + ('tenancy', '0002_tenant_group_optional'), + ('tenancy', '0003_unicode_literals'), + ('tenancy', '0004_tags'), + ('tenancy', '0005_change_logging'), + ('tenancy', '0006_custom_tag_models'), + ('tenancy', '0007_nested_tenantgroups'), + ('tenancy', '0008_nested_tenantgroups_rebuild'), + ('tenancy', '0009_standardize_description'), + ('tenancy', '0010_custom_field_data'), + ('tenancy', '0011_standardize_name_length'), + ('tenancy', '0012_standardize_models'), + ] + + operations = [ + migrations.CreateModel( + name='TenantGroup', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, unique=True)), + ('slug', models.SlugField(max_length=100, unique=True)), + ('description', models.CharField(blank=True, max_length=200)), + ('lft', models.PositiveIntegerField(editable=False)), + ('rght', models.PositiveIntegerField(editable=False)), + ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), + ('level', models.PositiveIntegerField(editable=False)), + ('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='tenancy.tenantgroup')), + ], + options={ + 'ordering': ['name'], + }, + ), + migrations.CreateModel( + name='Tenant', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, unique=True)), + ('slug', models.SlugField(max_length=100, unique=True)), + ('description', models.CharField(blank=True, max_length=200)), + ('comments', models.TextField(blank=True)), + ('group', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='tenants', to='tenancy.tenantgroup')), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ], + options={ + 'ordering': ['group', 'name'], + }, + ), + ] diff --git a/netbox/tenancy/migrations/0002_tenant_ordering.py b/netbox/tenancy/migrations/0002_tenant_ordering.py new file mode 100644 index 000000000..a72601930 --- /dev/null +++ b/netbox/tenancy/migrations/0002_tenant_ordering.py @@ -0,0 +1,15 @@ +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('tenancy', '0001_squashed_0012'), + ] + + operations = [ + migrations.AlterModelOptions( + name='tenant', + options={'ordering': ['name']}, + ), + ] diff --git a/netbox/tenancy/migrations/0003_contacts.py b/netbox/tenancy/migrations/0003_contacts.py new file mode 100644 index 000000000..eb247ee29 --- /dev/null +++ b/netbox/tenancy/migrations/0003_contacts.py @@ -0,0 +1,91 @@ +from utilities.json import CustomFieldJSONEncoder +from django.db import migrations, models +import django.db.models.deletion +import mptt.fields +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0062_clear_secrets_changelog'), + ('contenttypes', '0002_remove_content_type_name'), + ('tenancy', '0002_tenant_ordering'), + ] + + operations = [ + migrations.CreateModel( + name='ContactRole', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, unique=True)), + ('slug', models.SlugField(max_length=100, unique=True)), + ('description', models.CharField(blank=True, max_length=200)), + ], + options={ + 'ordering': ('name',), + }, + ), + migrations.CreateModel( + name='ContactGroup', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100)), + ('slug', models.SlugField(max_length=100)), + ('description', models.CharField(blank=True, max_length=200)), + ('lft', models.PositiveIntegerField(editable=False)), + ('rght', models.PositiveIntegerField(editable=False)), + ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), + ('level', models.PositiveIntegerField(editable=False)), + ('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='tenancy.contactgroup')), + ], + options={ + 'ordering': ['name'], + 'unique_together': {('parent', 'name')}, + }, + ), + migrations.CreateModel( + name='Contact', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100)), + ('title', models.CharField(blank=True, max_length=100)), + ('phone', models.CharField(blank=True, max_length=50)), + ('email', models.EmailField(blank=True, max_length=254)), + ('address', models.CharField(blank=True, max_length=200)), + ('comments', models.TextField(blank=True)), + ('group', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='contacts', to='tenancy.contactgroup')), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ], + options={ + 'ordering': ['name'], + 'unique_together': {('group', 'name')}, + }, + ), + migrations.CreateModel( + name='ContactAssignment', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('object_id', models.PositiveIntegerField()), + ('priority', models.CharField(blank=True, max_length=50)), + ('contact', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='assignments', to='tenancy.contact')), + ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')), + ('role', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='assignments', to='tenancy.contactrole')), + ], + options={ + 'ordering': ('priority', 'contact'), + 'unique_together': {('content_type', 'object_id', 'contact', 'role', 'priority')}, + }, + ), + ] diff --git a/netbox/tenancy/migrations/0004_extend_tag_support.py b/netbox/tenancy/migrations/0004_extend_tag_support.py new file mode 100644 index 000000000..942be38b5 --- /dev/null +++ b/netbox/tenancy/migrations/0004_extend_tag_support.py @@ -0,0 +1,30 @@ +# Generated by Django 3.2.8 on 2021-10-21 14:50 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0062_clear_secrets_changelog'), + ('tenancy', '0003_contacts'), + ] + + operations = [ + migrations.AddField( + model_name='contactgroup', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='contactrole', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='tenantgroup', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + ] diff --git a/netbox/tenancy/migrations/0005_standardize_id_fields.py b/netbox/tenancy/migrations/0005_standardize_id_fields.py new file mode 100644 index 000000000..05ea39066 --- /dev/null +++ b/netbox/tenancy/migrations/0005_standardize_id_fields.py @@ -0,0 +1,50 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0145_site_remove_deprecated_fields'), + ('tenancy', '0004_extend_tag_support'), + ] + + operations = [ + # Model IDs + migrations.AlterField( + model_name='contact', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='contactassignment', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='contactgroup', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='contactrole', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='tenant', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='tenantgroup', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + + # GFK IDs + migrations.AlterField( + model_name='contactassignment', + name='object_id', + field=models.PositiveBigIntegerField(), + ), + ] diff --git a/netbox/tenancy/migrations/0006_created_datetimefield.py b/netbox/tenancy/migrations/0006_created_datetimefield.py new file mode 100644 index 000000000..a972809e2 --- /dev/null +++ b/netbox/tenancy/migrations/0006_created_datetimefield.py @@ -0,0 +1,43 @@ +# Generated by Django 4.0.2 on 2022-02-08 18:54 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('tenancy', '0005_standardize_id_fields'), + ] + + operations = [ + migrations.AlterField( + model_name='contact', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='contactassignment', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='contactgroup', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='contactrole', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='tenant', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='tenantgroup', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + ] diff --git a/netbox/tenancy/migrations/0007_contact_link.py b/netbox/tenancy/migrations/0007_contact_link.py new file mode 100644 index 000000000..43b7495e5 --- /dev/null +++ b/netbox/tenancy/migrations/0007_contact_link.py @@ -0,0 +1,17 @@ +from django.db import migrations, models +import utilities.validators + + +class Migration(migrations.Migration): + + dependencies = [ + ('tenancy', '0006_created_datetimefield'), + ] + + operations = [ + migrations.AddField( + model_name='contact', + name='link', + field=models.URLField(blank=True), + ), + ] diff --git a/netbox/tenancy/migrations/0008_unique_constraints.py b/netbox/tenancy/migrations/0008_unique_constraints.py new file mode 100644 index 000000000..092878524 --- /dev/null +++ b/netbox/tenancy/migrations/0008_unique_constraints.py @@ -0,0 +1,35 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('tenancy', '0007_contact_link'), + ] + + operations = [ + migrations.AlterUniqueTogether( + name='contact', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='contactassignment', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='contactgroup', + unique_together=set(), + ), + migrations.AddConstraint( + model_name='contact', + constraint=models.UniqueConstraint(fields=('group', 'name'), name='tenancy_contact_unique_group_name'), + ), + migrations.AddConstraint( + model_name='contactassignment', + constraint=models.UniqueConstraint(fields=('content_type', 'object_id', 'contact', 'role'), name='tenancy_contactassignment_unique_object_contact_role'), + ), + migrations.AddConstraint( + model_name='contactgroup', + constraint=models.UniqueConstraint(fields=('parent', 'name'), name='tenancy_contactgroup_unique_parent_name'), + ), + ] diff --git a/netbox/tenancy/migrations/0009_standardize_description_comments.py b/netbox/tenancy/migrations/0009_standardize_description_comments.py new file mode 100644 index 000000000..af93b055c --- /dev/null +++ b/netbox/tenancy/migrations/0009_standardize_description_comments.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.2 on 2022-11-03 18:24 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('tenancy', '0008_unique_constraints'), + ] + + operations = [ + migrations.AddField( + model_name='contact', + name='description', + field=models.CharField(blank=True, max_length=200), + ), + ] diff --git a/netbox/tenancy/migrations/0010_tenant_relax_uniqueness.py b/netbox/tenancy/migrations/0010_tenant_relax_uniqueness.py new file mode 100644 index 000000000..6082fbfe9 --- /dev/null +++ b/netbox/tenancy/migrations/0010_tenant_relax_uniqueness.py @@ -0,0 +1,39 @@ +# Generated by Django 4.1.7 on 2023-03-01 01:01 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('tenancy', '0009_standardize_description_comments'), + ] + + operations = [ + migrations.AlterField( + model_name='tenant', + name='name', + field=models.CharField(max_length=100), + ), + migrations.AlterField( + model_name='tenant', + name='slug', + field=models.SlugField(max_length=100), + ), + migrations.AddConstraint( + model_name='tenant', + constraint=models.UniqueConstraint(fields=('group', 'name'), name='tenancy_tenant_unique_group_name', violation_error_message='Tenant name must be unique per group.'), + ), + migrations.AddConstraint( + model_name='tenant', + constraint=models.UniqueConstraint(condition=models.Q(('group__isnull', True)), fields=('name',), name='tenancy_tenant_unique_name'), + ), + migrations.AddConstraint( + model_name='tenant', + constraint=models.UniqueConstraint(fields=('group', 'slug'), name='tenancy_tenant_unique_group_slug', violation_error_message='Tenant slug must be unique per group.'), + ), + migrations.AddConstraint( + model_name='tenant', + constraint=models.UniqueConstraint(condition=models.Q(('group__isnull', True)), fields=('slug',), name='tenancy_tenant_unique_slug'), + ), + ] diff --git a/netbox/tenancy/migrations/0011_contactassignment_tags.py b/netbox/tenancy/migrations/0011_contactassignment_tags.py new file mode 100644 index 000000000..3c17d9ec1 --- /dev/null +++ b/netbox/tenancy/migrations/0011_contactassignment_tags.py @@ -0,0 +1,20 @@ +# Generated by Django 4.1.10 on 2023-07-08 07:17 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0097_customfield_remove_choices'), + ('tenancy', '0010_tenant_relax_uniqueness'), + ] + + operations = [ + migrations.AddField( + model_name='contactassignment', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + ] diff --git a/netbox/users/migrations/0001_initial.py b/netbox/users/migrations/0001_squashed_0011.py similarity index 59% rename from netbox/users/migrations/0001_initial.py rename to netbox/users/migrations/0001_squashed_0011.py index d135270ee..5efbcaec8 100644 --- a/netbox/users/migrations/0001_initial.py +++ b/netbox/users/migrations/0001_squashed_0011.py @@ -1,10 +1,9 @@ from django.conf import settings +import django.contrib.auth.models import django.contrib.postgres.fields import django.core.validators from django.db import migrations, models import django.db.models.deletion -import ipam.fields -import users.models class Migration(migrations.Migration): @@ -12,13 +11,12 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('contenttypes', '0002_remove_content_type_name'), migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('contenttypes', '0002_remove_content_type_name'), ('auth', '0012_alter_user_first_name_max_length'), ] replaces = [ - # Squashed for v3.0 ('users', '0001_api_tokens'), ('users', '0002_unicode_literals'), ('users', '0003_token_permissions'), @@ -30,95 +28,49 @@ class Migration(migrations.Migration): ('users', '0009_replicate_permissions'), ('users', '0010_update_jsonfield'), ('users', '0011_standardize_models'), - - # Squashed for v4.0 - ('users', '0002_standardize_id_fields'), - ('users', '0003_token_allowed_ips_last_used'), - ('users', '0004_netboxgroup_netboxuser'), ] operations = [ - migrations.CreateModel( - name='NetBoxGroup', - fields=[ - ], - options={ - 'verbose_name': 'group', - 'verbose_name_plural': 'groups', - 'ordering': ('name',), - 'proxy': True, - 'indexes': [], - 'constraints': [], - }, - bases=('auth.group',), - managers=[ - ('objects', users.models.NetBoxGroupManager()), - ], - ), - migrations.CreateModel( - name='NetBoxUser', - fields=[ - ], - options={ - 'verbose_name': 'user', - 'verbose_name_plural': 'users', - 'ordering': ('username',), - 'proxy': True, - 'indexes': [], - 'constraints': [], - }, - bases=('auth.user',), - managers=[ - ('objects', users.models.NetBoxUserManager()), - ], - ), migrations.CreateModel( name='UserConfig', fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)), ('data', models.JSONField(default=dict)), ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='config', to=settings.AUTH_USER_MODEL)), ], options={ - 'verbose_name': 'user preferences', - 'verbose_name_plural': 'user preferences', + 'verbose_name': 'User Preferences', + 'verbose_name_plural': 'User Preferences', 'ordering': ['user'], }, ), migrations.CreateModel( name='Token', fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), ('created', models.DateTimeField(auto_now_add=True)), ('expires', models.DateTimeField(blank=True, null=True)), - ('last_used', models.DateTimeField(blank=True, null=True)), ('key', models.CharField(max_length=40, unique=True, validators=[django.core.validators.MinLengthValidator(40)])), ('write_enabled', models.BooleanField(default=True)), ('description', models.CharField(blank=True, max_length=200)), - ('allowed_ips', django.contrib.postgres.fields.ArrayField(base_field=ipam.fields.IPNetworkField(), blank=True, null=True, size=None)), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tokens', to=settings.AUTH_USER_MODEL)), ], - options={ - 'verbose_name': 'token', - 'verbose_name_plural': 'tokens', - }, ), migrations.CreateModel( name='ObjectPermission', fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), ('name', models.CharField(max_length=100)), ('description', models.CharField(blank=True, max_length=200)), ('enabled', models.BooleanField(default=True)), ('actions', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=30), size=None)), ('constraints', models.JSONField(blank=True, null=True)), - ('groups', models.ManyToManyField(blank=True, related_name='object_permissions', to='auth.group')), - ('object_types', models.ManyToManyField(limit_choices_to=models.Q(models.Q(models.Q(('app_label__in', ['account', 'admin', 'auth', 'contenttypes', 'sessions', 'taggit', 'users']), _negated=True), models.Q(('app_label', 'auth'), ('model__in', ['group', 'user'])), models.Q(('app_label', 'users'), ('model__in', ['objectpermission', 'token'])), _connector='OR')), related_name='object_permissions', to='contenttypes.contenttype')), + ('groups', models.ManyToManyField(blank=True, related_name='object_permissions', to='auth.Group')), + ('object_types', models.ManyToManyField(limit_choices_to=models.Q(models.Q(models.Q(('app_label__in', ['account', 'admin', 'auth', 'contenttypes', 'sessions', 'taggit', 'users']), _negated=True), models.Q(('app_label', 'auth'), ('model__in', ['group', 'user'])), models.Q(('app_label', 'users'), ('model__in', ['objectpermission', 'token'])), _connector='OR')), related_name='object_permissions', to='contenttypes.ContentType')), ('users', models.ManyToManyField(blank=True, related_name='object_permissions', to=settings.AUTH_USER_MODEL)), ], options={ 'verbose_name': 'permission', - 'verbose_name_plural': 'permissions', 'ordering': ['name'], }, ), diff --git a/netbox/users/migrations/0002_standardize_id_fields.py b/netbox/users/migrations/0002_standardize_id_fields.py new file mode 100644 index 000000000..212ede6b1 --- /dev/null +++ b/netbox/users/migrations/0002_standardize_id_fields.py @@ -0,0 +1,27 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0145_site_remove_deprecated_fields'), + ('users', '0001_squashed_0011'), + ] + + operations = [ + migrations.AlterField( + model_name='objectpermission', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='token', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='userconfig', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + ] diff --git a/netbox/users/migrations/0003_token_allowed_ips_last_used.py b/netbox/users/migrations/0003_token_allowed_ips_last_used.py new file mode 100644 index 000000000..946226f75 --- /dev/null +++ b/netbox/users/migrations/0003_token_allowed_ips_last_used.py @@ -0,0 +1,23 @@ +import django.contrib.postgres.fields +from django.db import migrations, models +import ipam.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0002_standardize_id_fields'), + ] + + operations = [ + migrations.AddField( + model_name='token', + name='allowed_ips', + field=django.contrib.postgres.fields.ArrayField(base_field=ipam.fields.IPNetworkField(), blank=True, null=True, size=None), + ), + migrations.AddField( + model_name='token', + name='last_used', + field=models.DateTimeField(blank=True, null=True), + ), + ] diff --git a/netbox/users/migrations/0004_netboxgroup_netboxuser.py b/netbox/users/migrations/0004_netboxgroup_netboxuser.py new file mode 100644 index 000000000..59d941643 --- /dev/null +++ b/netbox/users/migrations/0004_netboxgroup_netboxuser.py @@ -0,0 +1,50 @@ +# Generated by Django 4.1.9 on 2023-06-06 18:15 + +import django.contrib.auth.models +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ('auth', '0012_alter_user_first_name_max_length'), + ('users', '0003_token_allowed_ips_last_used'), + ] + + operations = [ + migrations.CreateModel( + name='NetBoxGroup', + fields=[], + options={ + 'verbose_name': 'Group', + 'proxy': True, + 'indexes': [], + 'constraints': [], + }, + bases=('auth.group',), + managers=[ + ('objects', django.contrib.auth.models.GroupManager()), + ], + ), + migrations.CreateModel( + name='NetBoxUser', + fields=[], + options={ + 'verbose_name': 'User', + 'proxy': True, + 'indexes': [], + 'constraints': [], + }, + bases=('auth.user',), + managers=[ + ('objects', django.contrib.auth.models.UserManager()), + ], + ), + migrations.AlterModelOptions( + name='netboxgroup', + options={'ordering': ('name',), 'verbose_name': 'Group'}, + ), + migrations.AlterModelOptions( + name='netboxuser', + options={'ordering': ('username',), 'verbose_name': 'User'}, + ), + ] diff --git a/netbox/virtualization/migrations/0001_initial.py b/netbox/virtualization/migrations/0001_squashed_0022.py similarity index 57% rename from netbox/virtualization/migrations/0001_initial.py rename to netbox/virtualization/migrations/0001_squashed_0022.py index ddbb4bc8c..2a7894737 100644 --- a/netbox/virtualization/migrations/0001_initial.py +++ b/netbox/virtualization/migrations/0001_squashed_0022.py @@ -1,14 +1,12 @@ import dcim.fields +from utilities.json import CustomFieldJSONEncoder import django.core.validators from django.db import migrations, models import django.db.models.deletion -import django.db.models.functions.text import taggit.managers import utilities.fields -import utilities.json import utilities.ordering import utilities.query_functions -import utilities.tracking class Migration(migrations.Migration): @@ -16,14 +14,13 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('extras', '0001_initial'), + ('dcim', '0002_auto_20160622_1821'), ('ipam', '0001_initial'), - ('dcim', '0002_squashed'), + ('extras', '0001_initial'), ('tenancy', '0001_initial'), ] replaces = [ - # Squashed for v3.0 ('virtualization', '0001_virtualization'), ('virtualization', '0002_virtualmachine_add_status'), ('virtualization', '0003_cluster_add_site'), @@ -46,142 +43,80 @@ class Migration(migrations.Migration): ('virtualization', '0020_standardize_models'), ('virtualization', '0021_virtualmachine_vcpus_decimal'), ('virtualization', '0022_vminterface_parent'), - - # Squashed for v4.0 - ('virtualization', '0023_virtualmachine_natural_ordering'), - ('virtualization', '0024_cluster_relax_uniqueness'), - ('virtualization', '0025_extend_tag_support'), - ('virtualization', '0026_vminterface_bridge'), - ('virtualization', '0027_standardize_id_fields'), - ('virtualization', '0028_vminterface_vrf'), - ('virtualization', '0029_created_datetimefield'), - ('virtualization', '0030_cluster_status'), - ('virtualization', '0031_virtualmachine_site_device'), - ('virtualization', '0032_virtualmachine_update_sites'), - ('virtualization', '0033_unique_constraints'), - ('virtualization', '0034_standardize_description_comments'), - ('virtualization', '0035_virtualmachine_interface_count'), - ('virtualization', '0036_virtualmachine_config_template'), ] operations = [ migrations.CreateModel( name='Cluster', fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('created', models.DateField(auto_now_add=True, null=True)), ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('name', models.CharField(max_length=100)), - ('status', models.CharField(default='active', max_length=50)), - ], - options={ - 'verbose_name': 'cluster', - 'verbose_name_plural': 'clusters', - 'ordering': ['name'], - }, - ), - migrations.CreateModel( - name='VirtualMachine', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('local_context_data', models.JSONField(blank=True, null=True)), - ('name', models.CharField(max_length=64)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)), - ('status', models.CharField(default='active', max_length=50)), - ('vcpus', models.DecimalField(blank=True, decimal_places=2, max_digits=6, null=True, validators=[django.core.validators.MinValueValidator(0.01)])), - ('memory', models.PositiveIntegerField(blank=True, null=True)), - ('disk', models.PositiveIntegerField(blank=True, null=True)), - ('interface_count', utilities.fields.CounterCacheField(default=0, editable=False, to_field='virtual_machine', to_model='virtualization.VMInterface')), - ('cluster', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='virtual_machines', to='virtualization.cluster')), - ('config_template', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='%(class)ss', to='extras.configtemplate')), - ('device', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='virtual_machines', to='dcim.device')), - ('platform', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='virtual_machines', to='dcim.platform')), - ('primary_ip4', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='ipam.ipaddress')), - ('primary_ip6', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='ipam.ipaddress')), - ('role', models.ForeignKey(blank=True, limit_choices_to={'vm_role': True}, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='virtual_machines', to='dcim.devicerole')), - ('site', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='virtual_machines', to='dcim.site')), - ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), - ('tenant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='virtual_machines', to='tenancy.tenant')), - ], - options={ - 'verbose_name': 'virtual machine', - 'verbose_name_plural': 'virtual machines', - 'ordering': ('_name', 'pk'), - }, - ), - migrations.CreateModel( - name='VMInterface', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('enabled', models.BooleanField(default=True)), - ('mac_address', dcim.fields.MACAddressField(blank=True, null=True)), - ('mtu', models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(65536)])), - ('mode', models.CharField(blank=True, max_length=50)), - ('name', models.CharField(max_length=64)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize_interface)), - ('description', models.CharField(blank=True, max_length=200)), - ('bridge', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='bridge_interfaces', to='virtualization.vminterface')), - ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='child_interfaces', to='virtualization.vminterface')), - ('tagged_vlans', models.ManyToManyField(blank=True, related_name='vminterfaces_as_tagged', to='ipam.vlan')), - ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), - ('untagged_vlan', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='vminterfaces_as_untagged', to='ipam.vlan')), - ('virtual_machine', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='interfaces', to='virtualization.virtualmachine')), - ('vrf', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='vminterfaces', to='ipam.vrf')), - ], - options={ - 'verbose_name': 'interface', - 'verbose_name_plural': 'interfaces', - 'ordering': ('virtual_machine', utilities.query_functions.CollateAsChar('_name')), - }, - bases=(models.Model, utilities.tracking.TrackingModelMixin), - ), - migrations.CreateModel( - name='ClusterType', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), ('name', models.CharField(max_length=100, unique=True)), - ('slug', models.SlugField(max_length=100, unique=True)), - ('description', models.CharField(blank=True, max_length=200)), - ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ('comments', models.TextField(blank=True)), ], options={ - 'verbose_name': 'cluster type', - 'verbose_name_plural': 'cluster types', - 'ordering': ('name',), + 'ordering': ['name'], }, ), migrations.CreateModel( name='ClusterGroup', fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('created', models.DateField(auto_now_add=True, null=True)), ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), ('name', models.CharField(max_length=100, unique=True)), ('slug', models.SlugField(max_length=100, unique=True)), ('description', models.CharField(blank=True, max_length=200)), - ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), ], options={ - 'verbose_name': 'cluster group', - 'verbose_name_plural': 'cluster groups', 'ordering': ('name',), }, ), + migrations.CreateModel( + name='ClusterType', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100, unique=True)), + ('slug', models.SlugField(max_length=100, unique=True)), + ('description', models.CharField(blank=True, max_length=200)), + ], + options={ + 'ordering': ('name',), + }, + ), + migrations.CreateModel( + name='VirtualMachine', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('local_context_data', models.JSONField(blank=True, null=True)), + ('name', models.CharField(max_length=64)), + ('status', models.CharField(default='active', max_length=50)), + ('vcpus', models.DecimalField(blank=True, decimal_places=2, max_digits=6, null=True, validators=[django.core.validators.MinValueValidator(0.01)])), + ('memory', models.PositiveIntegerField(blank=True, null=True)), + ('disk', models.PositiveIntegerField(blank=True, null=True)), + ('comments', models.TextField(blank=True)), + ('cluster', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='virtual_machines', to='virtualization.cluster')), + ('platform', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='virtual_machines', to='dcim.platform')), + ('primary_ip4', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='ipam.ipaddress')), + ('primary_ip6', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='ipam.ipaddress')), + ('role', models.ForeignKey(blank=True, limit_choices_to={'vm_role': True}, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='virtual_machines', to='dcim.devicerole')), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ('tenant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='virtual_machines', to='tenancy.tenant')), + ], + options={ + 'ordering': ('name', 'pk'), + 'unique_together': {('cluster', 'tenant', 'name')}, + }, + ), migrations.AddField( model_name='cluster', name='group', @@ -207,24 +142,30 @@ class Migration(migrations.Migration): name='type', field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='clusters', to='virtualization.clustertype'), ), - migrations.AddConstraint( - model_name='vminterface', - constraint=models.UniqueConstraint(fields=('virtual_machine', 'name'), name='virtualization_vminterface_unique_virtual_machine_name'), - ), - migrations.AddConstraint( - model_name='virtualmachine', - constraint=models.UniqueConstraint(django.db.models.functions.text.Lower('name'), models.F('cluster'), models.F('tenant'), name='virtualization_virtualmachine_unique_name_cluster_tenant'), - ), - migrations.AddConstraint( - model_name='virtualmachine', - constraint=models.UniqueConstraint(django.db.models.functions.text.Lower('name'), models.F('cluster'), condition=models.Q(('tenant__isnull', True)), name='virtualization_virtualmachine_unique_name_cluster', violation_error_message='Virtual machine name must be unique per cluster.'), - ), - migrations.AddConstraint( - model_name='cluster', - constraint=models.UniqueConstraint(fields=('group', 'name'), name='virtualization_cluster_unique_group_name'), - ), - migrations.AddConstraint( - model_name='cluster', - constraint=models.UniqueConstraint(fields=('site', 'name'), name='virtualization_cluster_unique_site_name'), + migrations.CreateModel( + name='VMInterface', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('enabled', models.BooleanField(default=True)), + ('mac_address', dcim.fields.MACAddressField(blank=True, null=True)), + ('mtu', models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(65536)])), + ('mode', models.CharField(blank=True, max_length=50)), + ('name', models.CharField(max_length=64)), + ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize_interface)), + ('description', models.CharField(blank=True, max_length=200)), + ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='child_interfaces', to='virtualization.vminterface')), + ('tagged_vlans', models.ManyToManyField(blank=True, related_name='vminterfaces_as_tagged', to='ipam.VLAN')), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ('untagged_vlan', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='vminterfaces_as_untagged', to='ipam.vlan')), + ('virtual_machine', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='interfaces', to='virtualization.virtualmachine')), + ], + options={ + 'verbose_name': 'interface', + 'ordering': ('virtual_machine', utilities.query_functions.CollateAsChar('_name')), + 'unique_together': {('virtual_machine', 'name')}, + }, ), ] diff --git a/netbox/virtualization/migrations/0023_virtualmachine_natural_ordering.py b/netbox/virtualization/migrations/0023_virtualmachine_natural_ordering.py new file mode 100644 index 000000000..2fc2a38e0 --- /dev/null +++ b/netbox/virtualization/migrations/0023_virtualmachine_natural_ordering.py @@ -0,0 +1,32 @@ +from django.db import migrations +import utilities.fields +import utilities.ordering + + +def naturalize_virtualmachines(apps, schema_editor): + VirtualMachine = apps.get_model('virtualization', 'VirtualMachine') + for name in VirtualMachine.objects.values_list('name', flat=True).order_by('name').distinct(): + VirtualMachine.objects.filter(name=name).update(_name=utilities.ordering.naturalize(name, max_length=100)) + + +class Migration(migrations.Migration): + + dependencies = [ + ('virtualization', '0022_vminterface_parent'), + ] + + operations = [ + migrations.AlterModelOptions( + name='virtualmachine', + options={'ordering': ('_name', 'pk')}, + ), + migrations.AddField( + model_name='virtualmachine', + name='_name', + field=utilities.fields.NaturalOrderingField('name', max_length=100, blank=True, naturalize_function=utilities.ordering.naturalize), + ), + migrations.RunPython( + code=naturalize_virtualmachines, + reverse_code=migrations.RunPython.noop + ), + ] diff --git a/netbox/virtualization/migrations/0024_cluster_relax_uniqueness.py b/netbox/virtualization/migrations/0024_cluster_relax_uniqueness.py new file mode 100644 index 000000000..5ff214d29 --- /dev/null +++ b/netbox/virtualization/migrations/0024_cluster_relax_uniqueness.py @@ -0,0 +1,21 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0136_device_airflow'), + ('virtualization', '0023_virtualmachine_natural_ordering'), + ] + + operations = [ + migrations.AlterField( + model_name='cluster', + name='name', + field=models.CharField(max_length=100), + ), + migrations.AlterUniqueTogether( + name='cluster', + unique_together={('site', 'name'), ('group', 'name')}, + ), + ] diff --git a/netbox/virtualization/migrations/0025_extend_tag_support.py b/netbox/virtualization/migrations/0025_extend_tag_support.py new file mode 100644 index 000000000..c77aee194 --- /dev/null +++ b/netbox/virtualization/migrations/0025_extend_tag_support.py @@ -0,0 +1,25 @@ +# Generated by Django 3.2.8 on 2021-10-21 14:50 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0062_clear_secrets_changelog'), + ('virtualization', '0024_cluster_relax_uniqueness'), + ] + + operations = [ + migrations.AddField( + model_name='clustergroup', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + migrations.AddField( + model_name='clustertype', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + ] diff --git a/netbox/virtualization/migrations/0026_vminterface_bridge.py b/netbox/virtualization/migrations/0026_vminterface_bridge.py new file mode 100644 index 000000000..04909c72c --- /dev/null +++ b/netbox/virtualization/migrations/0026_vminterface_bridge.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2.8 on 2021-10-21 20:26 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('virtualization', '0025_extend_tag_support'), + ] + + operations = [ + migrations.AddField( + model_name='vminterface', + name='bridge', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='bridge_interfaces', to='virtualization.vminterface'), + ), + ] diff --git a/netbox/virtualization/migrations/0027_standardize_id_fields.py b/netbox/virtualization/migrations/0027_standardize_id_fields.py new file mode 100644 index 000000000..8c5ea8d70 --- /dev/null +++ b/netbox/virtualization/migrations/0027_standardize_id_fields.py @@ -0,0 +1,37 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0145_site_remove_deprecated_fields'), + ('virtualization', '0026_vminterface_bridge'), + ] + + operations = [ + migrations.AlterField( + model_name='cluster', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='clustergroup', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='clustertype', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='virtualmachine', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='vminterface', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + ] diff --git a/netbox/virtualization/migrations/0028_vminterface_vrf.py b/netbox/virtualization/migrations/0028_vminterface_vrf.py new file mode 100644 index 000000000..a188e1c60 --- /dev/null +++ b/netbox/virtualization/migrations/0028_vminterface_vrf.py @@ -0,0 +1,20 @@ +# Generated by Django 3.2.12 on 2022-02-07 14:39 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0056_standardize_id_fields'), + ('virtualization', '0027_standardize_id_fields'), + ] + + operations = [ + migrations.AddField( + model_name='vminterface', + name='vrf', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='vminterfaces', to='ipam.vrf'), + ), + ] diff --git a/netbox/virtualization/migrations/0029_created_datetimefield.py b/netbox/virtualization/migrations/0029_created_datetimefield.py new file mode 100644 index 000000000..d22547a25 --- /dev/null +++ b/netbox/virtualization/migrations/0029_created_datetimefield.py @@ -0,0 +1,38 @@ +# Generated by Django 4.0.2 on 2022-02-08 18:54 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('virtualization', '0028_vminterface_vrf'), + ] + + operations = [ + migrations.AlterField( + model_name='cluster', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='clustergroup', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='clustertype', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='virtualmachine', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='vminterface', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + ] diff --git a/netbox/virtualization/migrations/0030_cluster_status.py b/netbox/virtualization/migrations/0030_cluster_status.py new file mode 100644 index 000000000..e836bb914 --- /dev/null +++ b/netbox/virtualization/migrations/0030_cluster_status.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0.4 on 2022-05-19 19:36 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('virtualization', '0029_created_datetimefield'), + ] + + operations = [ + migrations.AddField( + model_name='cluster', + name='status', + field=models.CharField(default='active', max_length=50), + ), + ] diff --git a/netbox/virtualization/migrations/0031_virtualmachine_site_device.py b/netbox/virtualization/migrations/0031_virtualmachine_site_device.py new file mode 100644 index 000000000..85ea24455 --- /dev/null +++ b/netbox/virtualization/migrations/0031_virtualmachine_site_device.py @@ -0,0 +1,28 @@ +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0153_created_datetimefield'), + ('virtualization', '0030_cluster_status'), + ] + + operations = [ + migrations.AddField( + model_name='virtualmachine', + name='site', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='virtual_machines', to='dcim.site'), + ), + migrations.AddField( + model_name='virtualmachine', + name='device', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='virtual_machines', to='dcim.device'), + ), + migrations.AlterField( + model_name='virtualmachine', + name='cluster', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='virtual_machines', to='virtualization.cluster'), + ), + ] diff --git a/netbox/virtualization/migrations/0032_virtualmachine_update_sites.py b/netbox/virtualization/migrations/0032_virtualmachine_update_sites.py new file mode 100644 index 000000000..e9c52bfde --- /dev/null +++ b/netbox/virtualization/migrations/0032_virtualmachine_update_sites.py @@ -0,0 +1,27 @@ +from django.db import migrations + + +def update_virtualmachines_site(apps, schema_editor): + """ + Automatically set the site for all virtual machines. + """ + VirtualMachine = apps.get_model('virtualization', 'VirtualMachine') + + virtual_machines = VirtualMachine.objects.filter(cluster__site__isnull=False) + for vm in virtual_machines: + vm.site = vm.cluster.site + VirtualMachine.objects.bulk_update(virtual_machines, ['site']) + + +class Migration(migrations.Migration): + + dependencies = [ + ('virtualization', '0031_virtualmachine_site_device'), + ] + + operations = [ + migrations.RunPython( + code=update_virtualmachines_site, + reverse_code=migrations.RunPython.noop + ), + ] diff --git a/netbox/virtualization/migrations/0033_unique_constraints.py b/netbox/virtualization/migrations/0033_unique_constraints.py new file mode 100644 index 000000000..0624d3607 --- /dev/null +++ b/netbox/virtualization/migrations/0033_unique_constraints.py @@ -0,0 +1,44 @@ +from django.db import migrations, models +import django.db.models.functions.text + + +class Migration(migrations.Migration): + + dependencies = [ + ('virtualization', '0032_virtualmachine_update_sites'), + ] + + operations = [ + migrations.AlterUniqueTogether( + name='cluster', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='virtualmachine', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='vminterface', + unique_together=set(), + ), + migrations.AddConstraint( + model_name='cluster', + constraint=models.UniqueConstraint(fields=('group', 'name'), name='virtualization_cluster_unique_group_name'), + ), + migrations.AddConstraint( + model_name='cluster', + constraint=models.UniqueConstraint(fields=('site', 'name'), name='virtualization_cluster_unique_site_name'), + ), + migrations.AddConstraint( + model_name='virtualmachine', + constraint=models.UniqueConstraint(django.db.models.functions.text.Lower('name'), models.F('cluster'), models.F('tenant'), name='virtualization_virtualmachine_unique_name_cluster_tenant'), + ), + migrations.AddConstraint( + model_name='virtualmachine', + constraint=models.UniqueConstraint(django.db.models.functions.text.Lower('name'), models.F('cluster'), condition=models.Q(('tenant__isnull', True)), name='virtualization_virtualmachine_unique_name_cluster', violation_error_message='Virtual machine name must be unique per cluster.'), + ), + migrations.AddConstraint( + model_name='vminterface', + constraint=models.UniqueConstraint(fields=('virtual_machine', 'name'), name='virtualization_vminterface_unique_virtual_machine_name'), + ), + ] diff --git a/netbox/virtualization/migrations/0034_standardize_description_comments.py b/netbox/virtualization/migrations/0034_standardize_description_comments.py new file mode 100644 index 000000000..8517adeca --- /dev/null +++ b/netbox/virtualization/migrations/0034_standardize_description_comments.py @@ -0,0 +1,23 @@ +# Generated by Django 4.1.2 on 2022-11-03 18:24 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('virtualization', '0033_unique_constraints'), + ] + + operations = [ + migrations.AddField( + model_name='cluster', + name='description', + field=models.CharField(blank=True, max_length=200), + ), + migrations.AddField( + model_name='virtualmachine', + name='description', + field=models.CharField(blank=True, max_length=200), + ), + ] diff --git a/netbox/virtualization/migrations/0035_virtualmachine_interface_count.py b/netbox/virtualization/migrations/0035_virtualmachine_interface_count.py new file mode 100644 index 000000000..abed09d7e --- /dev/null +++ b/netbox/virtualization/migrations/0035_virtualmachine_interface_count.py @@ -0,0 +1,31 @@ +from django.db import migrations +from django.db.models import Count + +import utilities.fields +from utilities.counters import update_counts + + +def populate_virtualmachine_counts(apps, schema_editor): + VirtualMachine = apps.get_model('virtualization', 'VirtualMachine') + + update_counts(VirtualMachine, 'interface_count', 'interfaces') + + +class Migration(migrations.Migration): + dependencies = [ + ('virtualization', '0034_standardize_description_comments'), + ] + + operations = [ + migrations.AddField( + model_name='virtualmachine', + name='interface_count', + field=utilities.fields.CounterCacheField( + default=0, to_field='virtual_machine', to_model='virtualization.VMInterface' + ), + ), + migrations.RunPython( + code=populate_virtualmachine_counts, + reverse_code=migrations.RunPython.noop + ), + ] diff --git a/netbox/virtualization/migrations/0036_virtualmachine_config_template.py b/netbox/virtualization/migrations/0036_virtualmachine_config_template.py new file mode 100644 index 000000000..0456eea81 --- /dev/null +++ b/netbox/virtualization/migrations/0036_virtualmachine_config_template.py @@ -0,0 +1,20 @@ +# Generated by Django 4.1.10 on 2023-08-11 17:16 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0098_webhook_custom_field_data_webhook_tags'), + ('virtualization', '0035_virtualmachine_interface_count'), + ] + + operations = [ + migrations.AddField( + model_name='virtualmachine', + name='config_template', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='%(class)ss', to='extras.configtemplate'), + ), + ] diff --git a/netbox/wireless/migrations/0001_initial.py b/netbox/wireless/migrations/0001_wireless.py similarity index 56% rename from netbox/wireless/migrations/0001_initial.py rename to netbox/wireless/migrations/0001_wireless.py index 45b047086..9369df8a5 100644 --- a/netbox/wireless/migrations/0001_initial.py +++ b/netbox/wireless/migrations/0001_wireless.py @@ -1,9 +1,8 @@ +from utilities.json import CustomFieldJSONEncoder from django.db import migrations, models import django.db.models.deletion import mptt.fields import taggit.managers -import utilities.json -import wireless.models class Migration(migrations.Migration): @@ -11,105 +10,78 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('extras', '0001_initial'), - ('ipam', '0001_initial'), - ('dcim', '0002_squashed'), - ('tenancy', '0001_initial'), - ] - - replaces = [ - ('wireless', '0001_wireless'), - ('wireless', '0002_standardize_id_fields'), - ('wireless', '0003_created_datetimefield'), - ('wireless', '0004_wireless_tenancy'), - ('wireless', '0005_wirelesslink_interface_types'), - ('wireless', '0006_unique_constraints'), - ('wireless', '0007_standardize_description_comments'), - ('wireless', '0008_wirelesslan_status'), + ('dcim', '0139_rename_cable_peer'), + ('extras', '0062_clear_secrets_changelog'), + ('ipam', '0050_iprange'), ] operations = [ - migrations.CreateModel( - name='WirelessLink', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('auth_type', models.CharField(blank=True, max_length=50)), - ('auth_cipher', models.CharField(blank=True, max_length=50)), - ('auth_psk', models.CharField(blank=True, max_length=64)), - ('ssid', models.CharField(blank=True, max_length=32)), - ('status', models.CharField(default='connected', max_length=50)), - ('_interface_a_device', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='dcim.device')), - ('_interface_b_device', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='dcim.device')), - ('interface_a', models.ForeignKey(limit_choices_to=wireless.models.get_wireless_interface_types, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='dcim.interface')), - ('interface_b', models.ForeignKey(limit_choices_to=wireless.models.get_wireless_interface_types, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='dcim.interface')), - ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), - ('tenant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='wireless_links', to='tenancy.tenant')), - ], - options={ - 'verbose_name': 'wireless link', - 'verbose_name_plural': 'wireless links', - 'ordering': ['pk'], - }, - ), migrations.CreateModel( name='WirelessLANGroup', fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('created', models.DateField(auto_now_add=True, null=True)), ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), - ('description', models.CharField(blank=True, max_length=200)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), ('name', models.CharField(max_length=100, unique=True)), ('slug', models.SlugField(max_length=100, unique=True)), + ('description', models.CharField(blank=True, max_length=200)), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), ('lft', models.PositiveIntegerField(editable=False)), ('rght', models.PositiveIntegerField(editable=False)), ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), ('level', models.PositiveIntegerField(editable=False)), ('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='wireless.wirelesslangroup')), - ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), ], options={ - 'verbose_name': 'wireless LAN group', - 'verbose_name_plural': 'wireless LAN groups', 'ordering': ('name', 'pk'), + 'unique_together': {('parent', 'name')}, + 'verbose_name': 'Wireless LAN Group', }, ), migrations.CreateModel( name='WirelessLAN', fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('created', models.DateField(auto_now_add=True, null=True)), ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('ssid', models.CharField(max_length=32)), + ('group', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='wireless_lans', to='wireless.wirelesslangroup')), ('description', models.CharField(blank=True, max_length=200)), - ('comments', models.TextField(blank=True)), - ('auth_type', models.CharField(blank=True, max_length=50)), ('auth_cipher', models.CharField(blank=True, max_length=50)), ('auth_psk', models.CharField(blank=True, max_length=64)), - ('ssid', models.CharField(max_length=32)), - ('status', models.CharField(default='active', max_length=50)), - ('group', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='wireless_lans', to='wireless.wirelesslangroup')), + ('auth_type', models.CharField(blank=True, max_length=50)), ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), - ('tenant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='wireless_lans', to='tenancy.tenant')), ('vlan', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='ipam.vlan')), ], options={ - 'verbose_name': 'wireless LAN', - 'verbose_name_plural': 'wireless LANs', + 'verbose_name': 'Wireless LAN', 'ordering': ('ssid', 'pk'), }, ), - migrations.AddConstraint( - model_name='wirelesslink', - constraint=models.UniqueConstraint(fields=('interface_a', 'interface_b'), name='wireless_wirelesslink_unique_interfaces'), - ), - migrations.AddConstraint( - model_name='wirelesslangroup', - constraint=models.UniqueConstraint(fields=('parent', 'name'), name='wireless_wirelesslangroup_unique_parent_name'), + migrations.CreateModel( + name='WirelessLink', + fields=[ + ('created', models.DateField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)), + ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('ssid', models.CharField(blank=True, max_length=32)), + ('status', models.CharField(default='connected', max_length=50)), + ('description', models.CharField(blank=True, max_length=200)), + ('auth_cipher', models.CharField(blank=True, max_length=50)), + ('auth_psk', models.CharField(blank=True, max_length=64)), + ('auth_type', models.CharField(blank=True, max_length=50)), + ('_interface_a_device', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='dcim.device')), + ('_interface_b_device', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='dcim.device')), + ('interface_a', models.ForeignKey(limit_choices_to={'type__in': ['ieee802.11a', 'ieee802.11g', 'ieee802.11n', 'ieee802.11ac', 'ieee802.11ad', 'ieee802.11ax']}, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='dcim.interface')), + ('interface_b', models.ForeignKey(limit_choices_to={'type__in': ['ieee802.11a', 'ieee802.11g', 'ieee802.11n', 'ieee802.11ac', 'ieee802.11ad', 'ieee802.11ax']}, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='dcim.interface')), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ], + options={ + 'ordering': ['pk'], + 'unique_together': {('interface_a', 'interface_b')}, + }, ), ] diff --git a/netbox/wireless/migrations/0002_standardize_id_fields.py b/netbox/wireless/migrations/0002_standardize_id_fields.py new file mode 100644 index 000000000..d386d84fc --- /dev/null +++ b/netbox/wireless/migrations/0002_standardize_id_fields.py @@ -0,0 +1,27 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0145_site_remove_deprecated_fields'), + ('wireless', '0001_wireless'), + ] + + operations = [ + migrations.AlterField( + model_name='wirelesslan', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='wirelesslangroup', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='wirelesslink', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False), + ), + ] diff --git a/netbox/wireless/migrations/0003_created_datetimefield.py b/netbox/wireless/migrations/0003_created_datetimefield.py new file mode 100644 index 000000000..fe251248c --- /dev/null +++ b/netbox/wireless/migrations/0003_created_datetimefield.py @@ -0,0 +1,28 @@ +# Generated by Django 4.0.2 on 2022-02-08 18:54 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('wireless', '0002_standardize_id_fields'), + ] + + operations = [ + migrations.AlterField( + model_name='wirelesslan', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='wirelesslangroup', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='wirelesslink', + name='created', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + ] diff --git a/netbox/wireless/migrations/0004_wireless_tenancy.py b/netbox/wireless/migrations/0004_wireless_tenancy.py new file mode 100644 index 000000000..aa5837b0a --- /dev/null +++ b/netbox/wireless/migrations/0004_wireless_tenancy.py @@ -0,0 +1,25 @@ +# Generated by Django 4.0.5 on 2022-06-27 13:44 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('tenancy', '0007_contact_link'), + ('wireless', '0003_created_datetimefield'), + ] + + operations = [ + migrations.AddField( + model_name='wirelesslan', + name='tenant', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='wireless_lans', to='tenancy.tenant'), + ), + migrations.AddField( + model_name='wirelesslink', + name='tenant', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='wireless_links', to='tenancy.tenant'), + ), + ] diff --git a/netbox/wireless/migrations/0005_wirelesslink_interface_types.py b/netbox/wireless/migrations/0005_wirelesslink_interface_types.py new file mode 100644 index 000000000..0b3f88c5b --- /dev/null +++ b/netbox/wireless/migrations/0005_wirelesslink_interface_types.py @@ -0,0 +1,24 @@ +from django.db import migrations, models +import django.db.models.deletion +import wireless.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0161_cabling_cleanup'), + ('wireless', '0004_wireless_tenancy'), + ] + + operations = [ + migrations.AlterField( + model_name='wirelesslink', + name='interface_a', + field=models.ForeignKey(limit_choices_to=wireless.models.get_wireless_interface_types, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='dcim.interface'), + ), + migrations.AlterField( + model_name='wirelesslink', + name='interface_b', + field=models.ForeignKey(limit_choices_to=wireless.models.get_wireless_interface_types, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='dcim.interface'), + ), + ] diff --git a/netbox/wireless/migrations/0006_unique_constraints.py b/netbox/wireless/migrations/0006_unique_constraints.py new file mode 100644 index 000000000..f638ae1ab --- /dev/null +++ b/netbox/wireless/migrations/0006_unique_constraints.py @@ -0,0 +1,27 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('wireless', '0005_wirelesslink_interface_types'), + ] + + operations = [ + migrations.AlterUniqueTogether( + name='wirelesslangroup', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='wirelesslink', + unique_together=set(), + ), + migrations.AddConstraint( + model_name='wirelesslangroup', + constraint=models.UniqueConstraint(fields=('parent', 'name'), name='wireless_wirelesslangroup_unique_parent_name'), + ), + migrations.AddConstraint( + model_name='wirelesslink', + constraint=models.UniqueConstraint(fields=('interface_a', 'interface_b'), name='wireless_wirelesslink_unique_interfaces'), + ), + ] diff --git a/netbox/wireless/migrations/0007_standardize_description_comments.py b/netbox/wireless/migrations/0007_standardize_description_comments.py new file mode 100644 index 000000000..e6e1ce8dd --- /dev/null +++ b/netbox/wireless/migrations/0007_standardize_description_comments.py @@ -0,0 +1,23 @@ +# Generated by Django 4.1.2 on 2022-11-03 18:24 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('wireless', '0006_unique_constraints'), + ] + + operations = [ + migrations.AddField( + model_name='wirelesslan', + name='comments', + field=models.TextField(blank=True), + ), + migrations.AddField( + model_name='wirelesslink', + name='comments', + field=models.TextField(blank=True), + ), + ] diff --git a/netbox/wireless/migrations/0008_wirelesslan_status.py b/netbox/wireless/migrations/0008_wirelesslan_status.py new file mode 100644 index 000000000..e7832aba2 --- /dev/null +++ b/netbox/wireless/migrations/0008_wirelesslan_status.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.2 on 2022-11-04 17:07 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('wireless', '0007_standardize_description_comments'), + ] + + operations = [ + migrations.AddField( + model_name='wirelesslan', + name='status', + field=models.CharField(default='active', max_length=50), + ), + ]