diff --git a/netbox/circuits/api/serializers_/circuits.py b/netbox/circuits/api/serializers_/circuits.py index a68e49483..70644a7b7 100644 --- a/netbox/circuits/api/serializers_/circuits.py +++ b/netbox/circuits/api/serializers_/circuits.py @@ -59,8 +59,8 @@ class CircuitCircuitTerminationSerializer(WritableNestedSerializer): class Meta: model = CircuitTermination fields = [ - 'id', 'url', 'display_url', 'display', 'termination_type', 'termination_id', 'termination', 'provider_network', 'port_speed', 'upstream_speed', - 'xconnect_id', 'description', + 'id', 'url', 'display_url', 'display', 'termination_type', 'termination_id', 'termination', + 'provider_network', 'port_speed', 'upstream_speed', 'xconnect_id', 'description', ] @extend_schema_field(serializers.JSONField(allow_null=True)) @@ -138,9 +138,10 @@ class CircuitTerminationSerializer(NetBoxModelSerializer, CabledObjectSerializer class Meta: model = CircuitTermination fields = [ - 'id', 'url', 'display_url', 'display', 'circuit', 'term_side', 'termination_type', 'termination_id', 'termination', 'provider_network', 'port_speed', - 'upstream_speed', 'xconnect_id', 'pp_info', 'description', 'mark_connected', 'cable', 'cable_end', - 'link_peers', 'link_peers_type', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied', + 'id', 'url', 'display_url', 'display', 'circuit', 'term_side', 'termination_type', 'termination_id', + 'termination', 'provider_network', 'port_speed', 'upstream_speed', 'xconnect_id', 'pp_info', 'description', + 'mark_connected', 'cable', 'cable_end', 'link_peers', 'link_peers_type', 'tags', 'custom_fields', 'created', + 'last_updated', '_occupied', ] brief_fields = ('id', 'url', 'display', 'circuit', 'term_side', 'description', 'cable', '_occupied') diff --git a/netbox/circuits/filtersets.py b/netbox/circuits/filtersets.py index be36d45ac..825df9558 100644 --- a/netbox/circuits/filtersets.py +++ b/netbox/circuits/filtersets.py @@ -241,7 +241,9 @@ class CircuitFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilte class Meta: model = Circuit - fields = ('id', 'cid', 'description', 'install_date', 'termination_date', 'commit_rate', 'distance', 'distance_unit') + fields = ( + 'id', 'cid', 'description', 'install_date', 'termination_date', 'commit_rate', 'distance', 'distance_unit', + ) def search(self, queryset, name, value): if not value.strip(): @@ -336,8 +338,8 @@ class CircuitTerminationFilterSet(NetBoxModelFilterSet, CabledObjectFilterSet): class Meta: model = CircuitTermination fields = ( - 'id', 'termination_id', 'term_side', 'port_speed', 'upstream_speed', 'xconnect_id', 'description', 'mark_connected', - 'pp_info', 'cable_end', + 'id', 'termination_id', 'term_side', 'port_speed', 'upstream_speed', 'xconnect_id', 'description', + 'mark_connected', 'pp_info', 'cable_end', ) def search(self, queryset, name, value): diff --git a/netbox/circuits/forms/filtersets.py b/netbox/circuits/forms/filtersets.py index 00dc6bc5b..47ce24d97 100644 --- a/netbox/circuits/forms/filtersets.py +++ b/netbox/circuits/forms/filtersets.py @@ -121,7 +121,10 @@ class CircuitFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFi fieldsets = ( FieldSet('q', 'filter_id', 'tag'), FieldSet('provider_id', 'provider_account_id', 'provider_network_id', name=_('Provider')), - FieldSet('type_id', 'status', 'install_date', 'termination_date', 'commit_rate', 'distance', 'distance_unit', name=_('Attributes')), + FieldSet( + 'type_id', 'status', 'install_date', 'termination_date', 'commit_rate', 'distance', 'distance_unit', + name=_('Attributes') + ), FieldSet('region_id', 'site_group_id', 'site_id', name=_('Location')), FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')), FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')), diff --git a/netbox/circuits/migrations/0001_squashed.py b/netbox/circuits/migrations/0001_squashed.py index 96fa3c086..0b3d729e6 100644 --- a/netbox/circuits/migrations/0001_squashed.py +++ b/netbox/circuits/migrations/0001_squashed.py @@ -5,11 +5,9 @@ import django.db.models.deletion class Migration(migrations.Migration): - initial = True - dependencies = [ - ] + dependencies = [] replaces = [ ('circuits', '0001_initial'), @@ -98,7 +96,12 @@ class Migration(migrations.Migration): ('name', models.CharField(max_length=100)), ('description', models.CharField(blank=True, max_length=200)), ('comments', models.TextField(blank=True)), - ('provider', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='networks', to='circuits.provider')), + ( + 'provider', + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, related_name='networks', to='circuits.provider' + ), + ), ], options={ 'ordering': ('provider', 'name'), diff --git a/netbox/circuits/migrations/0002_squashed_0029.py b/netbox/circuits/migrations/0002_squashed_0029.py index 11fcbd6e6..cb61d8feb 100644 --- a/netbox/circuits/migrations/0002_squashed_0029.py +++ b/netbox/circuits/migrations/0002_squashed_0029.py @@ -4,7 +4,6 @@ import taggit.managers class Migration(migrations.Migration): - dependencies = [ ('dcim', '0001_initial'), ('contenttypes', '0002_remove_content_type_name'), @@ -58,32 +57,56 @@ class Migration(migrations.Migration): 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='circuits.provider' + ), ), migrations.AddField( model_name='circuit', @@ -93,26 +116,50 @@ class Migration(migrations.Migration): migrations.AddField( model_name='circuit', name='tenant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='tenancy.tenant'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='circuits', + to='tenancy.tenant', + ), ), migrations.AddField( model_name='circuit', name='termination_a', - field=models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='circuits.circuittermination'), + field=models.ForeignKey( + blank=True, + editable=False, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name='+', + to='circuits.circuittermination', + ), ), migrations.AddField( model_name='circuit', name='termination_z', - field=models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='circuits.circuittermination'), + field=models.ForeignKey( + blank=True, + editable=False, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name='+', + to='circuits.circuittermination', + ), ), migrations.AddField( model_name='circuit', name='type', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='circuits.circuittype'), + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='circuits.circuittype' + ), ), migrations.AddConstraint( model_name='providernetwork', - constraint=models.UniqueConstraint(fields=('provider', 'name'), name='circuits_providernetwork_provider_name'), + constraint=models.UniqueConstraint( + fields=('provider', 'name'), name='circuits_providernetwork_provider_name' + ), ), migrations.AlterUniqueTogether( name='providernetwork', diff --git a/netbox/circuits/migrations/0003_squashed_0037.py b/netbox/circuits/migrations/0003_squashed_0037.py index 69c3e1c68..c536e422f 100644 --- a/netbox/circuits/migrations/0003_squashed_0037.py +++ b/netbox/circuits/migrations/0003_squashed_0037.py @@ -5,7 +5,6 @@ import utilities.json class Migration(migrations.Migration): - replaces = [ ('circuits', '0003_extend_tag_support'), ('circuits', '0004_rename_cable_peer'), @@ -14,7 +13,7 @@ class Migration(migrations.Migration): ('circuits', '0034_created_datetimefield'), ('circuits', '0035_provider_asns'), ('circuits', '0036_circuit_termination_date_tags_custom_fields'), - ('circuits', '0037_new_cabling_models') + ('circuits', '0037_new_cabling_models'), ] dependencies = [ diff --git a/netbox/circuits/migrations/0038_squashed_0042.py b/netbox/circuits/migrations/0038_squashed_0042.py index f57fde3db..fa944b763 100644 --- a/netbox/circuits/migrations/0038_squashed_0042.py +++ b/netbox/circuits/migrations/0038_squashed_0042.py @@ -6,13 +6,12 @@ import utilities.json class Migration(migrations.Migration): - replaces = [ ('circuits', '0038_cabling_cleanup'), ('circuits', '0039_unique_constraints'), ('circuits', '0040_provider_remove_deprecated_fields'), ('circuits', '0041_standardize_description_comments'), - ('circuits', '0042_provideraccount') + ('circuits', '0042_provideraccount'), ] dependencies = [ @@ -51,11 +50,15 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='circuittermination', - constraint=models.UniqueConstraint(fields=('circuit', 'term_side'), name='circuits_circuittermination_unique_circuit_term_side'), + 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'), + constraint=models.UniqueConstraint( + fields=('provider', 'name'), name='circuits_providernetwork_unique_provider_name' + ), ), migrations.RemoveField( model_name='provider', @@ -84,12 +87,20 @@ class Migration(migrations.Migration): ('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=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')), + ( + '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={ @@ -98,11 +109,17 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='provideraccount', - constraint=models.UniqueConstraint(condition=models.Q(('name', ''), _negated=True), fields=('provider', 'name'), name='circuits_provideraccount_unique_provider_name'), + 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'), + constraint=models.UniqueConstraint( + fields=('provider', 'account'), name='circuits_provideraccount_unique_provider_account' + ), ), migrations.RemoveField( model_name='provider', @@ -111,7 +128,13 @@ class Migration(migrations.Migration): 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'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='circuits', + to='circuits.provideraccount', + ), preserve_default=False, ), migrations.AlterModelOptions( @@ -120,6 +143,8 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='circuit', - constraint=models.UniqueConstraint(fields=('provider_account', 'cid'), name='circuits_circuit_unique_provideraccount_cid'), + constraint=models.UniqueConstraint( + fields=('provider_account', 'cid'), name='circuits_circuit_unique_provideraccount_cid' + ), ), ] diff --git a/netbox/circuits/migrations/0044_circuit_groups.py b/netbox/circuits/migrations/0044_circuit_groups.py index 98c3b8f3d..08f6bc158 100644 --- a/netbox/circuits/migrations/0044_circuit_groups.py +++ b/netbox/circuits/migrations/0044_circuit_groups.py @@ -5,7 +5,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('circuits', '0043_circuittype_color'), ('extras', '0119_notifications'), diff --git a/netbox/circuits/migrations/0045_circuit_distance.py b/netbox/circuits/migrations/0045_circuit_distance.py index 6c970339d..9e512e7ee 100644 --- a/netbox/circuits/migrations/0045_circuit_distance.py +++ b/netbox/circuits/migrations/0045_circuit_distance.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('circuits', '0044_circuit_groups'), ] diff --git a/netbox/circuits/migrations/0046_charfield_null_choices.py b/netbox/circuits/migrations/0046_charfield_null_choices.py index 4ec21b750..2a8bcde90 100644 --- a/netbox/circuits/migrations/0046_charfield_null_choices.py +++ b/netbox/circuits/migrations/0046_charfield_null_choices.py @@ -15,7 +15,6 @@ def set_null_values(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('circuits', '0045_circuit_distance'), ] @@ -36,8 +35,5 @@ class Migration(migrations.Migration): name='cable_end', field=models.CharField(blank=True, max_length=1, null=True), ), - migrations.RunPython( - code=set_null_values, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=set_null_values, reverse_code=migrations.RunPython.noop), ] diff --git a/netbox/circuits/migrations/0047_circuittermination__termination.py b/netbox/circuits/migrations/0047_circuittermination__termination.py index 0cf2b424f..f78e17ec3 100644 --- a/netbox/circuits/migrations/0047_circuittermination__termination.py +++ b/netbox/circuits/migrations/0047_circuittermination__termination.py @@ -11,19 +11,17 @@ def copy_site_assignments(apps, schema_editor): Site = apps.get_model('dcim', 'Site') CircuitTermination.objects.filter(site__isnull=False).update( - termination_type=ContentType.objects.get_for_model(Site), - termination_id=models.F('site_id') + termination_type=ContentType.objects.get_for_model(Site), termination_id=models.F('site_id') ) ProviderNetwork = apps.get_model('circuits', 'ProviderNetwork') CircuitTermination.objects.filter(provider_network__isnull=False).update( termination_type=ContentType.objects.get_for_model(ProviderNetwork), - termination_id=models.F('provider_network_id') + termination_id=models.F('provider_network_id'), ) class Migration(migrations.Migration): - dependencies = [ ('circuits', '0046_charfield_null_choices'), ('contenttypes', '0002_remove_content_type_name'), @@ -41,17 +39,15 @@ class Migration(migrations.Migration): name='termination_type', field=models.ForeignKey( blank=True, - limit_choices_to=models.Q(('model__in', ('region', 'sitegroup', 'site', 'location', 'providernetwork'))), + limit_choices_to=models.Q( + ('model__in', ('region', 'sitegroup', 'site', 'location', 'providernetwork')) + ), null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype', ), ), - # Copy over existing site assignments - migrations.RunPython( - code=copy_site_assignments, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=copy_site_assignments, reverse_code=migrations.RunPython.noop), ] diff --git a/netbox/circuits/migrations/0048_circuitterminations_cached_relations.py b/netbox/circuits/migrations/0048_circuitterminations_cached_relations.py index 628579228..fc1cef0e5 100644 --- a/netbox/circuits/migrations/0048_circuitterminations_cached_relations.py +++ b/netbox/circuits/migrations/0048_circuitterminations_cached_relations.py @@ -20,7 +20,6 @@ def populate_denormalized_fields(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('circuits', '0047_circuittermination__termination'), ] @@ -70,13 +69,8 @@ class Migration(migrations.Migration): to='dcim.sitegroup', ), ), - # Populate denormalized FK values - migrations.RunPython( - code=populate_denormalized_fields, - reverse_code=migrations.RunPython.noop - ), - + migrations.RunPython(code=populate_denormalized_fields, reverse_code=migrations.RunPython.noop), # Delete the site ForeignKey migrations.RemoveField( model_name='circuittermination', diff --git a/netbox/circuits/migrations/0049_natural_ordering.py b/netbox/circuits/migrations/0049_natural_ordering.py index 1b4f565e8..556d6ec7c 100644 --- a/netbox/circuits/migrations/0049_natural_ordering.py +++ b/netbox/circuits/migrations/0049_natural_ordering.py @@ -2,7 +2,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('circuits', '0048_circuitterminations_cached_relations'), ('dcim', '0197_natural_sort_collation'), diff --git a/netbox/circuits/migrations/0050_virtual_circuits.py b/netbox/circuits/migrations/0050_virtual_circuits.py index df719b517..eb451b4ec 100644 --- a/netbox/circuits/migrations/0050_virtual_circuits.py +++ b/netbox/circuits/migrations/0050_virtual_circuits.py @@ -6,7 +6,6 @@ import utilities.json class Migration(migrations.Migration): - dependencies = [ ('circuits', '0049_natural_ordering'), ('dcim', '0196_qinq_svlan'), @@ -21,15 +20,43 @@ class Migration(migrations.Migration): ('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=utilities.json.CustomFieldJSONEncoder), + ), ('description', models.CharField(blank=True, max_length=200)), ('comments', models.TextField(blank=True)), ('cid', models.CharField(max_length=100)), ('status', models.CharField(default='active', max_length=50)), - ('provider_account', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='virtual_circuits', to='circuits.provideraccount')), - ('provider_network', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='virtual_circuits', to='circuits.providernetwork')), + ( + 'provider_account', + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='virtual_circuits', + to='circuits.provideraccount', + ), + ), + ( + 'provider_network', + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name='virtual_circuits', + to='circuits.providernetwork', + ), + ), ('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_circuits', to='tenancy.tenant')), + ( + 'tenant', + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='virtual_circuits', + to='tenancy.tenant', + ), + ), ], options={ 'verbose_name': 'circuit', @@ -43,12 +70,29 @@ class Migration(migrations.Migration): ('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=utilities.json.CustomFieldJSONEncoder), + ), ('role', models.CharField(default='peer', max_length=50)), ('description', models.CharField(blank=True, max_length=200)), - ('interface', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='virtual_circuit_termination', to='dcim.interface')), + ( + 'interface', + models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, + related_name='virtual_circuit_termination', + to='dcim.interface', + ), + ), ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), - ('virtual_circuit', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='terminations', to='circuits.virtualcircuit')), + ( + 'virtual_circuit', + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name='terminations', + to='circuits.virtualcircuit', + ), + ), ], options={ 'verbose_name': 'virtual circuit termination', @@ -58,10 +102,14 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='virtualcircuit', - constraint=models.UniqueConstraint(fields=('provider_network', 'cid'), name='circuits_virtualcircuit_unique_provider_network_cid'), + constraint=models.UniqueConstraint( + fields=('provider_network', 'cid'), name='circuits_virtualcircuit_unique_provider_network_cid' + ), ), migrations.AddConstraint( model_name='virtualcircuit', - constraint=models.UniqueConstraint(fields=('provider_account', 'cid'), name='circuits_virtualcircuit_unique_provideraccount_cid'), + constraint=models.UniqueConstraint( + fields=('provider_account', 'cid'), name='circuits_virtualcircuit_unique_provideraccount_cid' + ), ), ] diff --git a/netbox/circuits/models/circuits.py b/netbox/circuits/models/circuits.py index 85b22eaa5..5e910b5d5 100644 --- a/netbox/circuits/models/circuits.py +++ b/netbox/circuits/models/circuits.py @@ -11,7 +11,9 @@ from circuits.constants import * from dcim.models import CabledObjectModel from netbox.models import ChangeLoggedModel, OrganizationalModel, PrimaryModel from netbox.models.mixins import DistanceMixin -from netbox.models.features import ContactsMixin, CustomFieldsMixin, CustomLinksMixin, ExportTemplatesMixin, ImageAttachmentsMixin, TagsMixin +from netbox.models.features import ( + ContactsMixin, CustomFieldsMixin, CustomLinksMixin, ExportTemplatesMixin, ImageAttachmentsMixin, TagsMixin, +) from utilities.fields import ColorField __all__ = ( diff --git a/netbox/circuits/tables/circuits.py b/netbox/circuits/tables/circuits.py index ab9c661e6..dedb1534b 100644 --- a/netbox/circuits/tables/circuits.py +++ b/netbox/circuits/tables/circuits.py @@ -42,7 +42,8 @@ class CircuitTypeTable(NetBoxTable): class Meta(NetBoxTable.Meta): model = CircuitType fields = ( - 'pk', 'id', 'name', 'circuit_count', 'color', 'description', 'slug', 'tags', 'created', 'last_updated', 'actions', + 'pk', 'id', 'name', 'circuit_count', 'color', 'description', 'slug', 'tags', 'created', 'last_updated', + 'actions', ) default_columns = ('pk', 'name', 'circuit_count', 'description', 'slug') diff --git a/netbox/circuits/tests/test_api.py b/netbox/circuits/tests/test_api.py index 12c6b2a93..92fbbdedf 100644 --- a/netbox/circuits/tests/test_api.py +++ b/netbox/circuits/tests/test_api.py @@ -121,9 +121,15 @@ class CircuitTest(APIViewTestCases.APIViewTestCase): CircuitType.objects.bulk_create(circuit_types) circuits = ( - Circuit(cid='Circuit 1', provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0]), - Circuit(cid='Circuit 2', provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0]), - Circuit(cid='Circuit 3', provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0]), + Circuit( + cid='Circuit 1', provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0] + ), + Circuit( + cid='Circuit 2', provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0] + ), + Circuit( + cid='Circuit 3', provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0] + ), ) Circuit.objects.bulk_create(circuits) diff --git a/netbox/circuits/tests/test_filtersets.py b/netbox/circuits/tests/test_filtersets.py index 01b5e3105..6b7866665 100644 --- a/netbox/circuits/tests/test_filtersets.py +++ b/netbox/circuits/tests/test_filtersets.py @@ -226,12 +226,80 @@ class CircuitTestCase(TestCase, ChangeLoggedFilterSetTests): ProviderNetwork.objects.bulk_create(provider_networks) circuits = ( - Circuit(provider=providers[0], provider_account=provider_accounts[0], tenant=tenants[0], type=circuit_types[0], cid='Test Circuit 1', install_date='2020-01-01', termination_date='2021-01-01', commit_rate=1000, status=CircuitStatusChoices.STATUS_ACTIVE, description='foobar1', distance=10, distance_unit=DistanceUnitChoices.UNIT_FOOT), - Circuit(provider=providers[0], provider_account=provider_accounts[0], tenant=tenants[0], type=circuit_types[0], cid='Test Circuit 2', install_date='2020-01-02', termination_date='2021-01-02', commit_rate=2000, status=CircuitStatusChoices.STATUS_ACTIVE, description='foobar2', distance=20, distance_unit=DistanceUnitChoices.UNIT_METER), - Circuit(provider=providers[0], provider_account=provider_accounts[1], tenant=tenants[1], type=circuit_types[0], cid='Test Circuit 3', install_date='2020-01-03', termination_date='2021-01-03', commit_rate=3000, status=CircuitStatusChoices.STATUS_PLANNED, distance=30, distance_unit=DistanceUnitChoices.UNIT_METER), - Circuit(provider=providers[1], provider_account=provider_accounts[1], tenant=tenants[1], type=circuit_types[1], cid='Test Circuit 4', install_date='2020-01-04', termination_date='2021-01-04', commit_rate=4000, status=CircuitStatusChoices.STATUS_PLANNED), - Circuit(provider=providers[1], provider_account=provider_accounts[2], tenant=tenants[2], type=circuit_types[1], cid='Test Circuit 5', install_date='2020-01-05', termination_date='2021-01-05', commit_rate=5000, status=CircuitStatusChoices.STATUS_OFFLINE), - Circuit(provider=providers[1], provider_account=provider_accounts[2], tenant=tenants[2], type=circuit_types[1], cid='Test Circuit 6', install_date='2020-01-06', termination_date='2021-01-06', commit_rate=6000, status=CircuitStatusChoices.STATUS_OFFLINE), + Circuit( + provider=providers[0], + provider_account=provider_accounts[0], + tenant=tenants[0], + type=circuit_types[0], + cid='Test Circuit 1', + install_date='2020-01-01', + termination_date='2021-01-01', + commit_rate=1000, + status=CircuitStatusChoices.STATUS_ACTIVE, + description='foobar1', + distance=10, + distance_unit=DistanceUnitChoices.UNIT_FOOT, + ), + Circuit( + provider=providers[0], + provider_account=provider_accounts[0], + tenant=tenants[0], + type=circuit_types[0], + cid='Test Circuit 2', + install_date='2020-01-02', + termination_date='2021-01-02', + commit_rate=2000, + status=CircuitStatusChoices.STATUS_ACTIVE, + description='foobar2', + distance=20, + distance_unit=DistanceUnitChoices.UNIT_METER, + ), + Circuit( + provider=providers[0], + provider_account=provider_accounts[1], + tenant=tenants[1], + type=circuit_types[0], + cid='Test Circuit 3', + install_date='2020-01-03', + termination_date='2021-01-03', + commit_rate=3000, + status=CircuitStatusChoices.STATUS_PLANNED, + distance=30, + distance_unit=DistanceUnitChoices.UNIT_METER, + ), + Circuit( + provider=providers[1], + provider_account=provider_accounts[1], + tenant=tenants[1], + type=circuit_types[1], + cid='Test Circuit 4', + install_date='2020-01-04', + termination_date='2021-01-04', + commit_rate=4000, + status=CircuitStatusChoices.STATUS_PLANNED, + ), + Circuit( + provider=providers[1], + provider_account=provider_accounts[2], + tenant=tenants[2], + type=circuit_types[1], + cid='Test Circuit 5', + install_date='2020-01-05', + termination_date='2021-01-05', + commit_rate=5000, + status=CircuitStatusChoices.STATUS_OFFLINE, + ), + Circuit( + provider=providers[1], + provider_account=provider_accounts[2], + tenant=tenants[2], + type=circuit_types[1], + cid='Test Circuit 6', + install_date='2020-01-06', + termination_date='2021-01-06', + commit_rate=6000, + status=CircuitStatusChoices.STATUS_OFFLINE, + ), ) Circuit.objects.bulk_create(circuits) @@ -387,18 +455,64 @@ class CircuitTerminationTestCase(TestCase, ChangeLoggedFilterSetTests): ) Circuit.objects.bulk_create(circuits) - circuit_terminations = (( - CircuitTermination(circuit=circuits[0], termination=sites[0], term_side='A', port_speed=1000, upstream_speed=1000, xconnect_id='ABC', description='foobar1'), - CircuitTermination(circuit=circuits[0], termination=sites[1], term_side='Z', port_speed=1000, upstream_speed=1000, xconnect_id='DEF', description='foobar2'), - CircuitTermination(circuit=circuits[1], termination=sites[1], term_side='A', port_speed=2000, upstream_speed=2000, xconnect_id='GHI'), - CircuitTermination(circuit=circuits[1], termination=sites[2], term_side='Z', port_speed=2000, upstream_speed=2000, xconnect_id='JKL'), - CircuitTermination(circuit=circuits[2], termination=sites[2], term_side='A', port_speed=3000, upstream_speed=3000, xconnect_id='MNO'), - CircuitTermination(circuit=circuits[2], termination=sites[0], term_side='Z', port_speed=3000, upstream_speed=3000, xconnect_id='PQR'), + circuit_terminations = ( + CircuitTermination( + circuit=circuits[0], + termination=sites[0], + term_side='A', + port_speed=1000, + upstream_speed=1000, + xconnect_id='ABC', + description='foobar1', + ), + CircuitTermination( + circuit=circuits[0], + termination=sites[1], + term_side='Z', + port_speed=1000, + upstream_speed=1000, + xconnect_id='DEF', + description='foobar2', + ), + CircuitTermination( + circuit=circuits[1], + termination=sites[1], + term_side='A', + port_speed=2000, + upstream_speed=2000, + xconnect_id='GHI', + ), + CircuitTermination( + circuit=circuits[1], + termination=sites[2], + term_side='Z', + port_speed=2000, + upstream_speed=2000, + xconnect_id='JKL', + ), + CircuitTermination( + circuit=circuits[2], + termination=sites[2], + term_side='A', + port_speed=3000, + upstream_speed=3000, + xconnect_id='MNO', + ), + CircuitTermination( + circuit=circuits[2], + termination=sites[0], + term_side='Z', + port_speed=3000, + upstream_speed=3000, + xconnect_id='PQR', + ), CircuitTermination(circuit=circuits[3], termination=provider_networks[0], term_side='A'), CircuitTermination(circuit=circuits[4], termination=provider_networks[1], term_side='A'), CircuitTermination(circuit=circuits[5], termination=provider_networks[2], term_side='A'), - CircuitTermination(circuit=circuits[6], termination=provider_networks[0], term_side='A', mark_connected=True), - )) + CircuitTermination( + circuit=circuits[6], termination=provider_networks[0], term_side='A', mark_connected=True + ), + ) for ct in circuit_terminations: ct.save() diff --git a/netbox/circuits/tests/test_views.py b/netbox/circuits/tests/test_views.py index 321c2daa7..3a9bd4dff 100644 --- a/netbox/circuits/tests/test_views.py +++ b/netbox/circuits/tests/test_views.py @@ -141,9 +141,15 @@ class CircuitTestCase(ViewTestCases.PrimaryObjectViewTestCase): CircuitType.objects.bulk_create(circuittypes) circuits = ( - Circuit(cid='Circuit 1', provider=providers[0], provider_account=provider_accounts[0], type=circuittypes[0]), - Circuit(cid='Circuit 2', provider=providers[0], provider_account=provider_accounts[0], type=circuittypes[0]), - Circuit(cid='Circuit 3', provider=providers[0], provider_account=provider_accounts[0], type=circuittypes[0]), + Circuit( + cid='Circuit 1', provider=providers[0], provider_account=provider_accounts[0], type=circuittypes[0] + ), + Circuit( + cid='Circuit 2', provider=providers[0], provider_account=provider_accounts[0], type=circuittypes[0] + ), + Circuit( + cid='Circuit 3', provider=providers[0], provider_account=provider_accounts[0], type=circuittypes[0] + ), ) Circuit.objects.bulk_create(circuits) diff --git a/netbox/circuits/urls.py b/netbox/circuits/urls.py index b4746038d..56ba5eb8a 100644 --- a/netbox/circuits/urls.py +++ b/netbox/circuits/urls.py @@ -43,10 +43,30 @@ urlpatterns = [ path('virtual-circuits//', include(get_model_urls('circuits', 'virtualcircuit'))), # Virtual circuit terminations - path('virtual-circuit-terminations/', views.VirtualCircuitTerminationListView.as_view(), name='virtualcircuittermination_list'), - path('virtual-circuit-terminations/add/', views.VirtualCircuitTerminationEditView.as_view(), name='virtualcircuittermination_add'), - path('virtual-circuit-terminations/import/', views.VirtualCircuitTerminationBulkImportView.as_view(), name='virtualcircuittermination_import'), - path('virtual-circuit-terminations/edit/', views.VirtualCircuitTerminationBulkEditView.as_view(), name='virtualcircuittermination_bulk_edit'), - path('virtual-circuit-terminations/delete/', views.VirtualCircuitTerminationBulkDeleteView.as_view(), name='virtualcircuittermination_bulk_delete'), + path( + 'virtual-circuit-terminations/', + views.VirtualCircuitTerminationListView.as_view(), + name='virtualcircuittermination_list', + ), + path( + 'virtual-circuit-terminations/add/', + views.VirtualCircuitTerminationEditView.as_view(), + name='virtualcircuittermination_add', + ), + path( + 'virtual-circuit-terminations/import/', + views.VirtualCircuitTerminationBulkImportView.as_view(), + name='virtualcircuittermination_import', + ), + path( + 'virtual-circuit-terminations/edit/', + views.VirtualCircuitTerminationBulkEditView.as_view(), + name='virtualcircuittermination_bulk_edit', + ), + path( + 'virtual-circuit-terminations/delete/', + views.VirtualCircuitTerminationBulkDeleteView.as_view(), + name='virtualcircuittermination_bulk_delete', + ), path('virtual-circuit-terminations//', include(get_model_urls('circuits', 'virtualcircuittermination'))), ] diff --git a/netbox/core/api/schema.py b/netbox/core/api/schema.py index 1ac822b8c..fad907ac1 100644 --- a/netbox/core/api/schema.py +++ b/netbox/core/api/schema.py @@ -35,7 +35,10 @@ class ChoiceFieldFix(OpenApiSerializerFieldExtension): elif direction == "response": value = build_cf - label = {**build_basic_type(OpenApiTypes.STR), "enum": list(OrderedDict.fromkeys(self.target.choices.values()))} + label = { + **build_basic_type(OpenApiTypes.STR), + "enum": list(OrderedDict.fromkeys(self.target.choices.values())) + } return build_object_type( properties={ diff --git a/netbox/core/api/serializers_/jobs.py b/netbox/core/api/serializers_/jobs.py index 544dddb56..306287e88 100644 --- a/netbox/core/api/serializers_/jobs.py +++ b/netbox/core/api/serializers_/jobs.py @@ -22,7 +22,7 @@ class JobSerializer(BaseModelSerializer): class Meta: model = Job fields = [ - 'id', 'url', 'display_url', 'display', 'object_type', 'object_id', 'name', 'status', 'created', 'scheduled', 'interval', - 'started', 'completed', 'user', 'data', 'error', 'job_id', + 'id', 'url', 'display_url', 'display', 'object_type', 'object_id', 'name', 'status', 'created', 'scheduled', + 'interval', 'started', 'completed', 'user', 'data', 'error', 'job_id', ] brief_fields = ('url', 'created', 'completed', 'user', 'status') diff --git a/netbox/core/migrations/0001_squashed_0005.py b/netbox/core/migrations/0001_squashed_0005.py index 971370bf2..b89fa3b25 100644 --- a/netbox/core/migrations/0001_squashed_0005.py +++ b/netbox/core/migrations/0001_squashed_0005.py @@ -8,13 +8,12 @@ import utilities.json class Migration(migrations.Migration): - replaces = [ ('core', '0001_initial'), ('core', '0002_managedfile'), ('core', '0003_job'), ('core', '0004_replicate_jobresults'), - ('core', '0005_job_created_auto_now') + ('core', '0005_job_created_auto_now'), ] dependencies = [ @@ -30,7 +29,10 @@ class Migration(migrations.Migration): ('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=utilities.json.CustomFieldJSONEncoder), + ), ('description', models.CharField(blank=True, max_length=200)), ('comments', models.TextField(blank=True)), ('name', models.CharField(max_length=100, unique=True)), @@ -55,9 +57,28 @@ class Migration(migrations.Migration): ('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}$')])), + ( + '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')), + ( + 'source', + models.ForeignKey( + editable=False, + on_delete=django.db.models.deletion.CASCADE, + related_name='datafiles', + to='core.datasource', + ), + ), ], options={ 'ordering': ('source', 'path'), @@ -76,8 +97,18 @@ class Migration(migrations.Migration): fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), ('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')), + ( + '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={ 'indexes': [models.Index(fields=['object_type', 'object_id'], name='core_autosy_object__c17bac_idx')], @@ -97,8 +128,26 @@ class Migration(migrations.Migration): ('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')), + ( + '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={ @@ -108,7 +157,9 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='managedfile', - constraint=models.UniqueConstraint(fields=('file_root', 'file_path'), name='core_managedfile_unique_root_path'), + constraint=models.UniqueConstraint( + fields=('file_root', 'file_path'), name='core_managedfile_unique_root_path' + ), ), migrations.CreateModel( name='Job', @@ -118,14 +169,33 @@ class Migration(migrations.Migration): ('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)])), + ( + '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_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/0006_datasource_type_remove_choices.py b/netbox/core/migrations/0006_datasource_type_remove_choices.py index 0ad8d8854..7c9914298 100644 --- a/netbox/core/migrations/0006_datasource_type_remove_choices.py +++ b/netbox/core/migrations/0006_datasource_type_remove_choices.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('core', '0005_job_created_auto_now'), ] diff --git a/netbox/core/migrations/0007_job_add_error_field.py b/netbox/core/migrations/0007_job_add_error_field.py index e2e173bfd..3b0e02b56 100644 --- a/netbox/core/migrations/0007_job_add_error_field.py +++ b/netbox/core/migrations/0007_job_add_error_field.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('core', '0006_datasource_type_remove_choices'), ] diff --git a/netbox/core/migrations/0008_contenttype_proxy.py b/netbox/core/migrations/0008_contenttype_proxy.py index dee82a969..9acaf3ad7 100644 --- a/netbox/core/migrations/0008_contenttype_proxy.py +++ b/netbox/core/migrations/0008_contenttype_proxy.py @@ -3,7 +3,6 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ ('contenttypes', '0002_remove_content_type_name'), ('core', '0007_job_add_error_field'), @@ -12,8 +11,7 @@ class Migration(migrations.Migration): operations = [ migrations.CreateModel( name='ObjectType', - fields=[ - ], + fields=[], options={ 'proxy': True, 'indexes': [], diff --git a/netbox/core/migrations/0009_configrevision.py b/netbox/core/migrations/0009_configrevision.py index e7f817a16..6acd4531d 100644 --- a/netbox/core/migrations/0009_configrevision.py +++ b/netbox/core/migrations/0009_configrevision.py @@ -2,7 +2,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('core', '0008_contenttype_proxy'), ] diff --git a/netbox/core/migrations/0010_gfk_indexes.py b/netbox/core/migrations/0010_gfk_indexes.py index d51bc67ad..1e593a0c7 100644 --- a/netbox/core/migrations/0010_gfk_indexes.py +++ b/netbox/core/migrations/0010_gfk_indexes.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('core', '0009_configrevision'), ] diff --git a/netbox/core/migrations/0011_move_objectchange.py b/netbox/core/migrations/0011_move_objectchange.py index 2b41133ec..673763ce4 100644 --- a/netbox/core/migrations/0011_move_objectchange.py +++ b/netbox/core/migrations/0011_move_objectchange.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('contenttypes', '0002_remove_content_type_name'), ('core', '0010_gfk_indexes'), @@ -27,15 +26,49 @@ class Migration(migrations.Migration): ('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)), + ( + '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'], - 'indexes': [models.Index(fields=['changed_object_type', 'changed_object_id'], name='core_object_changed_c227ce_idx'), models.Index(fields=['related_object_type', 'related_object_id'], name='core_object_related_3375d6_idx')], + 'indexes': [ + models.Index( + fields=['changed_object_type', 'changed_object_id'], + name='core_object_changed_c227ce_idx', + ), + models.Index( + fields=['related_object_type', 'related_object_id'], + name='core_object_related_3375d6_idx', + ), + ], }, ), ], diff --git a/netbox/core/migrations/0012_job_object_type_optional.py b/netbox/core/migrations/0012_job_object_type_optional.py index 3c6664afc..3798b1285 100644 --- a/netbox/core/migrations/0012_job_object_type_optional.py +++ b/netbox/core/migrations/0012_job_object_type_optional.py @@ -3,7 +3,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('contenttypes', '0002_remove_content_type_name'), ('core', '0011_move_objectchange'), @@ -18,7 +17,7 @@ class Migration(migrations.Migration): null=True, on_delete=django.db.models.deletion.CASCADE, related_name='jobs', - to='contenttypes.contenttype' + to='contenttypes.contenttype', ), ), ] diff --git a/netbox/core/models/files.py b/netbox/core/models/files.py index 7b626a441..cc446bac7 100644 --- a/netbox/core/models/files.py +++ b/netbox/core/models/files.py @@ -93,9 +93,14 @@ class ManagedFile(SyncedDataMixin, models.Model): self.file_path = os.path.basename(self.data_path) # Ensure that the file root and path make a unique pair - if self._meta.model.objects.filter(file_root=self.file_root, file_path=self.file_path).exclude(pk=self.pk).exists(): + if self._meta.model.objects.filter( + file_root=self.file_root, file_path=self.file_path + ).exclude(pk=self.pk).exists(): raise ValidationError( - f"A {self._meta.verbose_name.lower()} with this file path already exists ({self.file_root}/{self.file_path}).") + _("A {model} with this file path already exists ({path}).").format( + model=self._meta.verbose_name.lower(), + path=f"{self.file_root}/{self.file_path}" + )) def delete(self, *args, **kwargs): # Delete file from disk diff --git a/netbox/core/models/jobs.py b/netbox/core/models/jobs.py index 82bfd72c8..5caa9cc2d 100644 --- a/netbox/core/models/jobs.py +++ b/netbox/core/models/jobs.py @@ -203,7 +203,17 @@ class Job(models.Model): job_end.send(self) @classmethod - def enqueue(cls, func, instance=None, name='', user=None, schedule_at=None, interval=None, immediate=False, **kwargs): + def enqueue( + cls, + func, + instance=None, + name='', + user=None, + schedule_at=None, + interval=None, + immediate=False, + **kwargs + ): """ Create a Job instance and enqueue a job using the given callable diff --git a/netbox/core/urls.py b/netbox/core/urls.py index 5db165a8b..b922c8bed 100644 --- a/netbox/core/urls.py +++ b/netbox/core/urls.py @@ -20,11 +20,27 @@ urlpatterns = ( # Background Tasks path('background-queues/', views.BackgroundQueueListView.as_view(), name='background_queue_list'), - path('background-queues///', views.BackgroundTaskListView.as_view(), name='background_task_list'), + path( + 'background-queues///', + views.BackgroundTaskListView.as_view(), + name='background_task_list' + ), path('background-tasks//', views.BackgroundTaskView.as_view(), name='background_task'), - path('background-tasks//delete/', views.BackgroundTaskDeleteView.as_view(), name='background_task_delete'), - path('background-tasks//requeue/', views.BackgroundTaskRequeueView.as_view(), name='background_task_requeue'), - path('background-tasks//enqueue/', views.BackgroundTaskEnqueueView.as_view(), name='background_task_enqueue'), + path( + 'background-tasks//delete/', + views.BackgroundTaskDeleteView.as_view(), + name='background_task_delete' + ), + path( + 'background-tasks//requeue/', + views.BackgroundTaskRequeueView.as_view(), + name='background_task_requeue' + ), + path( + 'background-tasks//enqueue/', + views.BackgroundTaskEnqueueView.as_view(), + name='background_task_enqueue' + ), path('background-tasks//stop/', views.BackgroundTaskStopView.as_view(), name='background_task_stop'), path('background-workers//', views.WorkerListView.as_view(), name='worker_list'), path('background-workers//', views.WorkerView.as_view(), name='worker'), diff --git a/netbox/dcim/api/serializers_/device_components.py b/netbox/dcim/api/serializers_/device_components.py index 12133ec65..a6767bb6f 100644 --- a/netbox/dcim/api/serializers_/device_components.py +++ b/netbox/dcim/api/serializers_/device_components.py @@ -351,9 +351,9 @@ class InventoryItemSerializer(NetBoxModelSerializer): class Meta: model = InventoryItem fields = [ - 'id', 'url', 'display_url', 'display', 'device', 'parent', 'name', 'label', 'status', 'role', 'manufacturer', - 'part_id', 'serial', 'asset_tag', 'discovered', 'description', 'component_type', 'component_id', - 'component', 'tags', 'custom_fields', 'created', 'last_updated', '_depth', + 'id', 'url', 'display_url', 'display', 'device', 'parent', 'name', 'label', 'status', 'role', + 'manufacturer', 'part_id', 'serial', 'asset_tag', 'discovered', 'description', 'component_type', + 'component_id', 'component', 'tags', 'custom_fields', 'created', 'last_updated', '_depth', ] brief_fields = ('id', 'url', 'display', 'device', 'name', 'description', '_depth') diff --git a/netbox/dcim/filtersets.py b/netbox/dcim/filtersets.py index f4d65d4bc..90a9993c2 100644 --- a/netbox/dcim/filtersets.py +++ b/netbox/dcim/filtersets.py @@ -312,8 +312,8 @@ class RackTypeFilterSet(NetBoxModelFilterSet): class Meta: model = RackType fields = ( - 'id', 'model', 'slug', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', - 'mounting_depth', 'weight', 'max_weight', 'weight_unit', 'description', + 'id', 'model', 'slug', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_depth', + 'outer_unit', 'mounting_depth', 'weight', 'max_weight', 'weight_unit', 'description', ) def search(self, queryset, name, value): diff --git a/netbox/dcim/forms/bulk_import.py b/netbox/dcim/forms/bulk_import.py index b8a7a007c..a2352d806 100644 --- a/netbox/dcim/forms/bulk_import.py +++ b/netbox/dcim/forms/bulk_import.py @@ -428,7 +428,10 @@ class ModuleTypeImportForm(NetBoxModelImportForm): class Meta: model = ModuleType - fields = ['manufacturer', 'model', 'part_number', 'description', 'airflow', 'weight', 'weight_unit', 'comments', 'tags'] + fields = [ + 'manufacturer', 'model', 'part_number', 'description', 'airflow', 'weight', 'weight_unit', 'comments', + 'tags', + ] class DeviceRoleImportForm(NetBoxModelImportForm): @@ -800,7 +803,10 @@ class PowerOutletImportForm(NetBoxModelImportForm): class Meta: model = PowerOutlet - fields = ('device', 'name', 'label', 'type', 'color', 'mark_connected', 'power_port', 'feed_leg', 'description', 'tags') + fields = ( + 'device', 'name', 'label', 'type', 'color', 'mark_connected', 'power_port', 'feed_leg', 'description', + 'tags', + ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -1114,8 +1120,8 @@ class InventoryItemImportForm(NetBoxModelImportForm): class Meta: model = InventoryItem fields = ( - 'device', 'name', 'label', 'status', 'role', 'manufacturer', 'parent', 'part_id', 'serial', 'asset_tag', 'discovered', - 'description', 'tags', 'component_type', 'component_name', + 'device', 'name', 'label', 'status', 'role', 'manufacturer', 'parent', 'part_id', 'serial', 'asset_tag', + 'discovered', 'description', 'tags', 'component_type', 'component_name', ) def __init__(self, *args, **kwargs): diff --git a/netbox/dcim/forms/common.py b/netbox/dcim/forms/common.py index d30ac0784..04c53b384 100644 --- a/netbox/dcim/forms/common.py +++ b/netbox/dcim/forms/common.py @@ -136,7 +136,10 @@ class ModuleCommonForm(forms.Form): if len(module_bays) != template.name.count(MODULE_TOKEN): raise forms.ValidationError( - _("Cannot install module with placeholder values in a module bay tree {level} in tree but {tokens} placeholders given.").format( + _( + "Cannot install module with placeholder values in a module bay tree {level} in tree " + "but {tokens} placeholders given." + ).format( level=len(module_bays), tokens=template.name.count(MODULE_TOKEN) ) ) diff --git a/netbox/dcim/forms/connections.py b/netbox/dcim/forms/connections.py index 324f8ecfd..5e5d83b0b 100644 --- a/netbox/dcim/forms/connections.py +++ b/netbox/dcim/forms/connections.py @@ -111,9 +111,15 @@ def get_cable_form(a_type, b_type): if self.instance and self.instance.pk: # Initialize A/B terminations when modifying an existing Cable instance - if a_type and self.instance.a_terminations and a_ct == ContentType.objects.get_for_model(self.instance.a_terminations[0]): + if ( + a_type and self.instance.a_terminations and + a_ct == ContentType.objects.get_for_model(self.instance.a_terminations[0]) + ): self.initial['a_terminations'] = self.instance.a_terminations - if b_type and self.instance.b_terminations and b_ct == ContentType.objects.get_for_model(self.instance.b_terminations[0]): + if ( + b_type and self.instance.b_terminations and + b_ct == ContentType.objects.get_for_model(self.instance.b_terminations[0]) + ): self.initial['b_terminations'] = self.instance.b_terminations else: # Need to clear terminations if swapped type - but need to do it only diff --git a/netbox/dcim/forms/model_forms.py b/netbox/dcim/forms/model_forms.py index 8a19b14e7..37cce9060 100644 --- a/netbox/dcim/forms/model_forms.py +++ b/netbox/dcim/forms/model_forms.py @@ -266,7 +266,10 @@ class RackForm(TenancyForm, NetBoxModelForm): comments = CommentField() fieldsets = ( - FieldSet('site', 'location', 'name', 'status', 'role', 'rack_type', 'description', 'airflow', 'tags', name=_('Rack')), + FieldSet( + 'site', 'location', 'name', 'status', 'role', 'rack_type', 'description', 'airflow', 'tags', + name=_('Rack') + ), FieldSet('facility_id', 'serial', 'asset_tag', name=_('Inventory Control')), FieldSet('tenant_group', 'tenant', name=_('Tenancy')), ) @@ -1007,7 +1010,8 @@ class InterfaceTemplateForm(ModularComponentTemplateForm): class Meta: model = InterfaceTemplate fields = [ - 'device_type', 'module_type', 'name', 'label', 'type', 'mgmt_only', 'enabled', 'description', 'poe_mode', 'poe_type', 'bridge', 'rf_role', + 'device_type', 'module_type', 'name', 'label', 'type', 'mgmt_only', 'enabled', 'description', 'poe_mode', + 'poe_type', 'bridge', 'rf_role', ] @@ -1189,7 +1193,10 @@ class InventoryItemTemplateForm(ComponentTemplateForm): break elif component_type and component_id: # When adding the InventoryItem from a component page - if content_type := ContentType.objects.filter(MODULAR_COMPONENT_TEMPLATE_MODELS).filter(pk=component_type).first(): + content_type = ContentType.objects.filter( + MODULAR_COMPONENT_TEMPLATE_MODELS + ).filter(pk=component_type).first() + if content_type: if component := content_type.model_class().objects.filter(pk=component_id).first(): initial[content_type.model] = component @@ -1301,16 +1308,16 @@ class PowerOutletForm(ModularDeviceComponentForm): fieldsets = ( FieldSet( - 'device', 'module', 'name', 'label', 'type', 'color', 'power_port', 'feed_leg', 'mark_connected', 'description', - 'tags', + 'device', 'module', 'name', 'label', 'type', 'color', 'power_port', 'feed_leg', 'mark_connected', + 'description', 'tags', ), ) class Meta: model = PowerOutlet fields = [ - 'device', 'module', 'name', 'label', 'type', 'color', 'power_port', 'feed_leg', 'mark_connected', 'description', - 'tags', + 'device', 'module', 'name', 'label', 'type', 'color', 'power_port', 'feed_leg', 'mark_connected', + 'description', 'tags', ] @@ -1611,7 +1618,10 @@ class InventoryItemForm(DeviceComponentForm): ) fieldsets = ( - FieldSet('device', 'parent', 'name', 'label', 'status', 'role', 'description', 'tags', name=_('Inventory Item')), + FieldSet( + 'device', 'parent', 'name', 'label', 'status', 'role', 'description', 'tags', + name=_('Inventory Item') + ), FieldSet('manufacturer', 'part_id', 'serial', 'asset_tag', name=_('Hardware')), FieldSet( TabbedGroups( diff --git a/netbox/dcim/forms/object_create.py b/netbox/dcim/forms/object_create.py index 85c613b8c..6f6cd8f7c 100644 --- a/netbox/dcim/forms/object_create.py +++ b/netbox/dcim/forms/object_create.py @@ -416,7 +416,8 @@ class VirtualChassisCreateForm(NetBoxModelForm): class Meta: model = VirtualChassis fields = [ - 'name', 'domain', 'description', 'region', 'site_group', 'site', 'rack', 'members', 'initial_position', 'tags', + 'name', 'domain', 'description', 'region', 'site_group', 'site', 'rack', 'members', 'initial_position', + 'tags', ] def clean(self): diff --git a/netbox/dcim/forms/object_import.py b/netbox/dcim/forms/object_import.py index d46ef83ad..821f91402 100644 --- a/netbox/dcim/forms/object_import.py +++ b/netbox/dcim/forms/object_import.py @@ -136,7 +136,8 @@ class FrontPortTemplateImportForm(forms.ModelForm): class Meta: model = FrontPortTemplate fields = [ - 'device_type', 'module_type', 'name', 'type', 'color', 'rear_port', 'rear_port_position', 'label', 'description', + 'device_type', 'module_type', 'name', 'type', 'color', 'rear_port', 'rear_port_position', 'label', + 'description', ] diff --git a/netbox/dcim/graphql/types.py b/netbox/dcim/graphql/types.py index 7aa4ef8a0..1020861f4 100644 --- a/netbox/dcim/graphql/types.py +++ b/netbox/dcim/graphql/types.py @@ -482,7 +482,9 @@ class LocationType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, Organi return self.cluster_set.all() @strawberry_django.field - def circuit_terminations(self) -> List[Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]]: + def circuit_terminations(self) -> List[ + Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')] + ]: return self.circuit_terminations.all() @@ -728,7 +730,9 @@ class RegionType(VLANGroupsMixin, ContactsMixin, OrganizationalObjectType): return self.cluster_set.all() @strawberry_django.field - def circuit_terminations(self) -> List[Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]]: + def circuit_terminations(self) -> List[ + Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')] + ]: return self.circuit_terminations.all() @@ -760,7 +764,9 @@ class SiteType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, NetBoxObje return self.cluster_set.all() @strawberry_django.field - def circuit_terminations(self) -> List[Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]]: + def circuit_terminations(self) -> List[ + Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')] + ]: return self.circuit_terminations.all() @@ -784,7 +790,9 @@ class SiteGroupType(VLANGroupsMixin, ContactsMixin, OrganizationalObjectType): return self.cluster_set.all() @strawberry_django.field - def circuit_terminations(self) -> List[Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]]: + def circuit_terminations(self) -> List[ + Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')] + ]: return self.circuit_terminations.all() diff --git a/netbox/dcim/migrations/0001_squashed.py b/netbox/dcim/migrations/0001_squashed.py index cf0ef4816..f08fe1d70 100644 --- a/netbox/dcim/migrations/0001_squashed.py +++ b/netbox/dcim/migrations/0001_squashed.py @@ -13,11 +13,9 @@ import utilities.validators class Migration(migrations.Migration): - initial = True - dependencies = [ - ] + dependencies = [] replaces = [ ('dcim', '0001_initial'), @@ -64,7 +62,12 @@ class Migration(migrations.Migration): ('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)), + ( + '_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)), @@ -83,7 +86,12 @@ class Migration(migrations.Migration): ('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)), + ( + '_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)), @@ -100,7 +108,12 @@ class Migration(migrations.Migration): ('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)), + ( + '_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)), @@ -119,7 +132,12 @@ class Migration(migrations.Migration): ('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)), + ( + '_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)), @@ -137,14 +155,34 @@ class Migration(migrations.Migration): ('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)), + ( + '_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)])), + ( + '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)])), + ( + '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={ @@ -159,7 +197,12 @@ class Migration(migrations.Migration): ('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)), + ( + '_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)), ], @@ -174,7 +217,12 @@ class Migration(migrations.Migration): ('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)), + ( + '_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)), ], @@ -228,13 +276,27 @@ class Migration(migrations.Migration): ('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)), + ( + '_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)])), + ( + 'rear_port_position', + models.PositiveSmallIntegerField( + default=1, + validators=[ + django.core.validators.MinValueValidator(1), + django.core.validators.MaxValueValidator(1024), + ], + ), + ), ], options={ 'ordering': ('device', '_name'), @@ -247,11 +309,25 @@ class Migration(migrations.Migration): ('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)), + ( + '_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)])), + ( + 'rear_port_position', + models.PositiveSmallIntegerField( + default=1, + validators=[ + django.core.validators.MinValueValidator(1), + django.core.validators.MaxValueValidator(1024), + ], + ), + ), ], options={ 'ordering': ('device_type', '_name'), @@ -271,9 +347,24 @@ class Migration(migrations.Migration): ('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)])), + ( + '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)), + ( + '_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)), ], @@ -290,7 +381,12 @@ class Migration(migrations.Migration): ('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)), + ( + '_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)), ], @@ -306,7 +402,12 @@ class Migration(migrations.Migration): ('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)), + ( + '_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)), @@ -388,8 +489,19 @@ class Migration(migrations.Migration): ('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)])), + ( + '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)), ], @@ -405,7 +517,12 @@ class Migration(migrations.Migration): ('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)), + ( + '_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)), @@ -424,7 +541,12 @@ class Migration(migrations.Migration): ('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)), + ( + '_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)), @@ -455,14 +577,29 @@ class Migration(migrations.Migration): ('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)), + ( + '_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)])), + ( + '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'), @@ -475,12 +612,27 @@ class Migration(migrations.Migration): ('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)), + ( + '_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)])), + ( + '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'), @@ -494,14 +646,28 @@ class Migration(migrations.Migration): ('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)), + ( + '_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)])), + ( + '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)), @@ -519,7 +685,10 @@ class Migration(migrations.Migration): ('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)), + ( + 'units', + django.contrib.postgres.fields.ArrayField(base_field=models.PositiveSmallIntegerField(), size=None), + ), ('description', models.CharField(max_length=200)), ], options={ @@ -550,13 +719,27 @@ class Migration(migrations.Migration): ('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)), + ( + '_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)])), + ( + 'positions', + models.PositiveSmallIntegerField( + default=1, + validators=[ + django.core.validators.MinValueValidator(1), + django.core.validators.MaxValueValidator(1024), + ], + ), + ), ], options={ 'ordering': ('device', '_name'), @@ -569,11 +752,25 @@ class Migration(migrations.Migration): ('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)), + ( + '_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)])), + ( + 'positions', + models.PositiveSmallIntegerField( + default=1, + validators=[ + django.core.validators.MinValueValidator(1), + django.core.validators.MaxValueValidator(1024), + ], + ), + ), ], options={ 'ordering': ('device_type', '_name'), @@ -606,7 +803,12 @@ class Migration(migrations.Migration): ('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)), + ( + '_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)), @@ -654,7 +856,16 @@ class Migration(migrations.Migration): ('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')), + ( + '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', diff --git a/netbox/dcim/migrations/0002_squashed.py b/netbox/dcim/migrations/0002_squashed.py index 786167680..2e830560f 100644 --- a/netbox/dcim/migrations/0002_squashed.py +++ b/netbox/dcim/migrations/0002_squashed.py @@ -6,7 +6,6 @@ import taggit.managers class Migration(migrations.Migration): - dependencies = [ ('dcim', '0001_initial'), migrations.swappable_dependency(settings.AUTH_USER_MODEL), @@ -28,17 +27,35 @@ class Migration(migrations.Migration): 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'), + 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'), + 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'), + 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', @@ -48,32 +65,56 @@ class Migration(migrations.Migration): 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device' + ), ), migrations.AddField( model_name='rearport', @@ -83,7 +124,9 @@ class Migration(migrations.Migration): migrations.AddField( model_name='rackreservation', name='rack', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reservations', to='dcim.rack'), + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, related_name='reservations', to='dcim.rack' + ), ), migrations.AddField( model_name='rackreservation', @@ -93,7 +136,13 @@ class Migration(migrations.Migration): 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'), + 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', @@ -103,12 +152,24 @@ class Migration(migrations.Migration): 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'), + 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'), + 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', @@ -123,32 +184,52 @@ class Migration(migrations.Migration): 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device' + ), ), migrations.AddField( model_name='powerport', @@ -158,7 +239,9 @@ class Migration(migrations.Migration): migrations.AddField( model_name='powerpanel', name='location', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='dcim.location'), + field=models.ForeignKey( + blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='dcim.location' + ), ), migrations.AddField( model_name='powerpanel', @@ -173,37 +256,63 @@ class Migration(migrations.Migration): 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + 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', @@ -213,27 +322,45 @@ class Migration(migrations.Migration): 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'), + 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'), + 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'), + 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'), + 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, related_name='powerfeeds', to='dcim.rack'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='powerfeeds', + to='dcim.rack', + ), ), migrations.AddField( model_name='powerfeed', @@ -243,32 +370,60 @@ class Migration(migrations.Migration): 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + 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', @@ -278,36 +433,62 @@ class Migration(migrations.Migration): 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + 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_0130.py b/netbox/dcim/migrations/0003_squashed_0130.py index 592aaf9a8..0248d9ba1 100644 --- a/netbox/dcim/migrations/0003_squashed_0130.py +++ b/netbox/dcim/migrations/0003_squashed_0130.py @@ -4,7 +4,6 @@ import taggit.managers class Migration(migrations.Migration): - dependencies = [ ('dcim', '0002_auto_20160622_1821'), ('virtualization', '0001_virtualization'), @@ -160,37 +159,61 @@ class Migration(migrations.Migration): 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, related_name='frontports', to='dcim.rearport' + ), ), migrations.AddField( model_name='frontport', @@ -200,7 +223,9 @@ class Migration(migrations.Migration): migrations.AddField( model_name='devicetype', name='manufacturer', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='device_types', to='dcim.manufacturer'), + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, related_name='device_types', to='dcim.manufacturer' + ), ), migrations.AddField( model_name='devicetype', @@ -210,17 +235,27 @@ class Migration(migrations.Migration): 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'), + 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'), + 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'), + 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', @@ -230,47 +265,89 @@ class Migration(migrations.Migration): 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='dcim.site' + ), ), migrations.AddField( model_name='device', @@ -280,37 +357,63 @@ class Migration(migrations.Migration): 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device' + ), ), migrations.AddField( model_name='consoleserverport', @@ -320,27 +423,41 @@ class Migration(migrations.Migration): 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'), + 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'), + 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'), + 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'), + 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'), + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device' + ), ), migrations.AddField( model_name='consoleport', @@ -350,22 +467,34 @@ class Migration(migrations.Migration): 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'), + 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'), + 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'), + 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'), + field=models.ForeignKey( + blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='dcim.device' + ), ), migrations.AddField( model_name='cable', @@ -375,12 +504,64 @@ class Migration(migrations.Migration): 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'), + 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'), + 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', @@ -456,7 +637,11 @@ class Migration(migrations.Migration): ), migrations.AlterUniqueTogether( name='device', - unique_together={('rack', 'position', 'face'), ('virtual_chassis', 'vc_position'), ('site', 'tenant', 'name')}, + unique_together={ + ('rack', 'position', 'face'), + ('virtual_chassis', 'vc_position'), + ('site', 'tenant', 'name'), + }, ), migrations.AlterUniqueTogether( name='consoleserverporttemplate', diff --git a/netbox/dcim/migrations/0131_squashed_0159.py b/netbox/dcim/migrations/0131_squashed_0159.py index f7e7cfdb2..3866e8cc8 100644 --- a/netbox/dcim/migrations/0131_squashed_0159.py +++ b/netbox/dcim/migrations/0131_squashed_0159.py @@ -10,7 +10,6 @@ import utilities.ordering class Migration(migrations.Migration): - replaces = [ ('dcim', '0131_consoleport_speed'), ('dcim', '0132_cable_length'), @@ -40,7 +39,7 @@ class Migration(migrations.Migration): ('dcim', '0156_location_status'), ('dcim', '0157_new_cabling_models'), ('dcim', '0158_populate_cable_terminations'), - ('dcim', '0159_populate_cable_paths') + ('dcim', '0159_populate_cable_paths'), ] dependencies = [ @@ -96,17 +95,35 @@ class Migration(migrations.Migration): 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'), + 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='location', name='tenant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='locations', to='tenancy.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'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='cables', + to='tenancy.tenant', + ), ), migrations.AddField( model_name='devicetype', @@ -148,7 +165,9 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='location', - constraint=models.UniqueConstraint(condition=models.Q(('parent', None)), fields=('site', 'name'), name='dcim_location_name'), + constraint=models.UniqueConstraint( + condition=models.Q(('parent', None)), fields=('site', 'name'), name='dcim_location_name' + ), ), migrations.AddConstraint( model_name='location', @@ -156,7 +175,9 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='location', - constraint=models.UniqueConstraint(condition=models.Q(('parent', None)), fields=('site', 'slug'), name='dcim_location_slug'), + constraint=models.UniqueConstraint( + condition=models.Q(('parent', None)), fields=('site', 'slug'), name='dcim_location_slug' + ), ), migrations.AddConstraint( model_name='region', @@ -164,7 +185,9 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='region', - constraint=models.UniqueConstraint(condition=models.Q(('parent', None)), fields=('name',), name='dcim_region_name'), + constraint=models.UniqueConstraint( + condition=models.Q(('parent', None)), fields=('name',), name='dcim_region_name' + ), ), migrations.AddConstraint( model_name='region', @@ -172,7 +195,9 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='region', - constraint=models.UniqueConstraint(condition=models.Q(('parent', None)), fields=('slug',), name='dcim_region_slug'), + constraint=models.UniqueConstraint( + condition=models.Q(('parent', None)), fields=('slug',), name='dcim_region_slug' + ), ), migrations.AddConstraint( model_name='sitegroup', @@ -180,7 +205,9 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='sitegroup', - constraint=models.UniqueConstraint(condition=models.Q(('parent', None)), fields=('name',), name='dcim_sitegroup_name'), + constraint=models.UniqueConstraint( + condition=models.Q(('parent', None)), fields=('name',), name='dcim_sitegroup_name' + ), ), migrations.AddConstraint( model_name='sitegroup', @@ -188,7 +215,9 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='sitegroup', - constraint=models.UniqueConstraint(condition=models.Q(('parent', None)), fields=('slug',), name='dcim_sitegroup_slug'), + constraint=models.UniqueConstraint( + condition=models.Q(('parent', None)), fields=('slug',), name='dcim_sitegroup_slug' + ), ), migrations.AddField( model_name='devicerole', @@ -328,7 +357,9 @@ class Migration(migrations.Migration): migrations.AddField( model_name='interface', name='tx_power', - field=models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(127)]), + field=models.PositiveSmallIntegerField( + blank=True, null=True, validators=[django.core.validators.MaxValueValidator(127)] + ), ), migrations.AddField( model_name='interface', @@ -338,7 +369,13 @@ class Migration(migrations.Migration): 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'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name='+', + to='wireless.wirelesslink', + ), ), migrations.AddField( model_name='site', @@ -348,12 +385,24 @@ class Migration(migrations.Migration): 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'), + 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'), + field=models.OneToOneField( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name='+', + to='ipam.ipaddress', + ), ), migrations.RemoveField( model_name='site', @@ -372,7 +421,23 @@ class Migration(migrations.Migration): name='contact_phone', ), migrations.RunSQL( - sql="\n DO $$\n DECLARE\n idx record;\n BEGIN\n FOR idx IN\n SELECT indexname AS old_name,\n replace(indexname, 'module', 'inventoryitem') AS new_name\n FROM pg_indexes\n WHERE schemaname = 'public' AND\n tablename = 'dcim_inventoryitem' AND\n indexname LIKE 'dcim_module_%'\n LOOP\n EXECUTE format(\n 'ALTER INDEX %I RENAME TO %I;',\n idx.old_name,\n idx.new_name\n );\n END LOOP;\n END$$;\n ", + sql="""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', @@ -405,49 +470,99 @@ class Migration(migrations.Migration): 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + 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.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=utilities.json.CustomFieldJSONEncoder), + ), ('id', models.BigAutoField(auto_created=True, 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')), + ( + '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={ @@ -460,14 +575,27 @@ class Migration(migrations.Migration): fields=[ ('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=utilities.json.CustomFieldJSONEncoder), + ), ('id', models.BigAutoField(auto_created=True, 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)), + ( + '_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')), + ( + '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={ @@ -480,15 +608,35 @@ class Migration(migrations.Migration): fields=[ ('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=utilities.json.CustomFieldJSONEncoder), + ), ('id', models.BigAutoField(auto_created=True, 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')), + ( + '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={ @@ -498,72 +646,156 @@ class Migration(migrations.Migration): 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + 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'), + 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', @@ -598,7 +830,10 @@ class Migration(migrations.Migration): fields=[ ('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=utilities.json.CustomFieldJSONEncoder), + ), ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), ('name', models.CharField(max_length=100, unique=True)), ('slug', models.SlugField(max_length=100, unique=True)), @@ -613,7 +848,13 @@ class Migration(migrations.Migration): 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'), + 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', @@ -623,12 +864,39 @@ class Migration(migrations.Migration): 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'), + 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='interface', name='vrf', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='interfaces', to='ipam.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', @@ -952,7 +1220,12 @@ class Migration(migrations.Migration): ('last_updated', models.DateTimeField(auto_now=True, null=True)), ('id', models.BigAutoField(auto_created=True, 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)), + ( + '_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)), @@ -961,11 +1234,67 @@ class Migration(migrations.Migration): ('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')), + ( + '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'), @@ -989,11 +1318,21 @@ class Migration(migrations.Migration): ('last_updated', models.DateTimeField(auto_now=True, null=True)), ('id', models.BigAutoField(auto_created=True, 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)), + ( + '_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')), + ( + 'device_type', + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype' + ), + ), ], options={ 'ordering': ('device_type', '_name'), @@ -1088,7 +1427,16 @@ class Migration(migrations.Migration): 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)]), + 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), + ], + ), ), migrations.AddField( model_name='interface', @@ -1121,12 +1469,66 @@ class Migration(migrations.Migration): ('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')), + ( + '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'), @@ -1134,7 +1536,9 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='cabletermination', - constraint=models.UniqueConstraint(fields=('termination_type', 'termination_id'), name='dcim_cable_termination_unique_termination'), + constraint=models.UniqueConstraint( + fields=('termination_type', 'termination_id'), name='dcim_cable_termination_unique_termination' + ), ), migrations.RenameField( model_name='cablepath', diff --git a/netbox/dcim/migrations/0160_squashed_0166.py b/netbox/dcim/migrations/0160_squashed_0166.py index 440a8115e..0deb58bab 100644 --- a/netbox/dcim/migrations/0160_squashed_0166.py +++ b/netbox/dcim/migrations/0160_squashed_0166.py @@ -6,7 +6,6 @@ import utilities.json class Migration(migrations.Migration): - replaces = [ ('dcim', '0160_populate_cable_ends'), ('dcim', '0161_cabling_cleanup'), @@ -14,7 +13,7 @@ class Migration(migrations.Migration): ('dcim', '0163_weight_fields'), ('dcim', '0164_rack_mounting_depth'), ('dcim', '0165_standardize_description_comments'), - ('dcim', '0166_virtualdevicecontext') + ('dcim', '0166_virtualdevicecontext'), ] dependencies = [ @@ -275,7 +274,9 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='cabletermination', - constraint=models.UniqueConstraint(fields=('termination_type', 'termination_id'), name='dcim_cabletermination_unique_termination'), + constraint=models.UniqueConstraint( + fields=('termination_type', 'termination_id'), name='dcim_cabletermination_unique_termination' + ), ), migrations.AddConstraint( model_name='consoleport', @@ -283,39 +284,64 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='consoleporttemplate', - constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_consoleporttemplate_unique_device_type_name'), + 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'), + 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'), + 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'), + 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'), + 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'), + 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.'), + 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'), + 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'), + constraint=models.UniqueConstraint( + fields=('virtual_chassis', 'vc_position'), name='dcim_device_unique_virtual_chassis_vc_position' + ), ), migrations.AddConstraint( model_name='devicebay', @@ -323,15 +349,21 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='devicebaytemplate', - constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_devicebaytemplate_unique_device_type_name'), + 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'), + 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'), + constraint=models.UniqueConstraint( + fields=('manufacturer', 'slug'), name='dcim_devicetype_unique_manufacturer_slug' + ), ), migrations.AddConstraint( model_name='frontport', @@ -339,19 +371,27 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='frontport', - constraint=models.UniqueConstraint(fields=('rear_port', 'rear_port_position'), name='dcim_frontport_unique_rear_port_position'), + 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'), + 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'), + 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'), + constraint=models.UniqueConstraint( + fields=('rear_port', 'rear_port_position'), name='dcim_frontporttemplate_unique_rear_port_position' + ), ), migrations.AddConstraint( model_name='interface', @@ -359,27 +399,46 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='interfacetemplate', - constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_interfacetemplate_unique_device_type_name'), + 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'), + 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'), + 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'), + 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.'), + 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.'), + 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', @@ -387,15 +446,21 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='modulebaytemplate', - constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_modulebaytemplate_unique_device_type_name'), + 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'), + 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'), + constraint=models.UniqueConstraint( + fields=('power_panel', 'name'), name='dcim_powerfeed_unique_power_panel_name' + ), ), migrations.AddConstraint( model_name='poweroutlet', @@ -403,11 +468,15 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='poweroutlettemplate', - constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_poweroutlettemplate_unique_device_type_name'), + 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'), + constraint=models.UniqueConstraint( + fields=('module_type', 'name'), name='dcim_poweroutlettemplate_unique_module_type_name' + ), ), migrations.AddConstraint( model_name='powerpanel', @@ -419,11 +488,15 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='powerporttemplate', - constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_powerporttemplate_unique_device_type_name'), + 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'), + constraint=models.UniqueConstraint( + fields=('module_type', 'name'), name='dcim_powerporttemplate_unique_module_type_name' + ), ), migrations.AddConstraint( model_name='rack', @@ -431,7 +504,9 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='rack', - constraint=models.UniqueConstraint(fields=('location', 'facility_id'), name='dcim_rack_unique_location_facility_id'), + constraint=models.UniqueConstraint( + fields=('location', 'facility_id'), name='dcim_rack_unique_location_facility_id' + ), ), migrations.AddConstraint( model_name='rearport', @@ -439,27 +514,51 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='rearporttemplate', - constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_rearporttemplate_unique_device_type_name'), + 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'), + 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.'), + 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.'), + 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.'), + 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.'), + 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.AddField( model_name='devicetype', @@ -592,17 +691,56 @@ class Migration(migrations.Migration): ('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=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')), + ( + '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')), + ( + 'tenant', + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='vdcs', + to='tenancy.tenant', + ), + ), ], options={ 'ordering': ['name'], @@ -615,7 +753,9 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='virtualdevicecontext', - constraint=models.UniqueConstraint(fields=('device', 'identifier'), name='dcim_virtualdevicecontext_device_identifier'), + constraint=models.UniqueConstraint( + fields=('device', 'identifier'), name='dcim_virtualdevicecontext_device_identifier' + ), ), migrations.AddConstraint( model_name='virtualdevicecontext', diff --git a/netbox/dcim/migrations/0167_squashed_0182.py b/netbox/dcim/migrations/0167_squashed_0182.py index 735cb3efa..d0ad5379f 100644 --- a/netbox/dcim/migrations/0167_squashed_0182.py +++ b/netbox/dcim/migrations/0167_squashed_0182.py @@ -6,7 +6,6 @@ import utilities.fields class Migration(migrations.Migration): - replaces = [ ('dcim', '0167_module_status'), ('dcim', '0168_interface_template_enabled'), @@ -24,7 +23,7 @@ class Migration(migrations.Migration): ('dcim', '0179_interfacetemplate_rf_role'), ('dcim', '0180_powerfeed_tenant'), ('dcim', '0181_rename_device_role_device_role'), - ('dcim', '0182_zero_length_cable_fix') + ('dcim', '0182_zero_length_cable_fix'), ] dependencies = [ @@ -48,27 +47,57 @@ class Migration(migrations.Migration): 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'), + 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='devicetype', name='default_platform', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.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='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'), + 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'), + 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'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='platforms', + to='extras.configtemplate', + ), ), migrations.AddField( model_name='cabletermination', @@ -83,22 +112,30 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='powerport', name='allocated_draw', - field=models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)]), + 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)]), + 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)]), + 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)]), + field=models.PositiveIntegerField( + blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)] + ), ), migrations.RemoveField( model_name='platform', @@ -126,112 +163,160 @@ class Migration(migrations.Migration): 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'), + 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='console_port_count', - field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.ConsolePort'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, to_field='device', to_model='dcim.ConsolePort' + ), ), migrations.AddField( model_name='device', name='console_server_port_count', - field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.ConsoleServerPort'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, to_field='device', to_model='dcim.ConsoleServerPort' + ), ), migrations.AddField( model_name='device', name='power_port_count', - field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.PowerPort'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, to_field='device', to_model='dcim.PowerPort' + ), ), migrations.AddField( model_name='device', name='power_outlet_count', - field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.PowerOutlet'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, to_field='device', to_model='dcim.PowerOutlet' + ), ), migrations.AddField( model_name='device', name='interface_count', - field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.Interface'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, to_field='device', to_model='dcim.Interface' + ), ), migrations.AddField( model_name='device', name='front_port_count', - field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.FrontPort'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, to_field='device', to_model='dcim.FrontPort' + ), ), migrations.AddField( model_name='device', name='rear_port_count', - field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.RearPort'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, to_field='device', to_model='dcim.RearPort' + ), ), migrations.AddField( model_name='device', name='device_bay_count', - field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.DeviceBay'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, to_field='device', to_model='dcim.DeviceBay' + ), ), migrations.AddField( model_name='device', name='module_bay_count', - field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.ModuleBay'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, to_field='device', to_model='dcim.ModuleBay' + ), ), migrations.AddField( model_name='device', name='inventory_item_count', - field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.InventoryItem'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, to_field='device', to_model='dcim.InventoryItem' + ), ), migrations.AddField( model_name='devicetype', name='console_port_template_count', - field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.ConsolePortTemplate'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, 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, editable=False, to_field='device_type', to_model='dcim.ConsoleServerPortTemplate'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, to_field='device_type', to_model='dcim.ConsoleServerPortTemplate' + ), ), migrations.AddField( model_name='devicetype', name='power_port_template_count', - field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.PowerPortTemplate'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, to_field='device_type', to_model='dcim.PowerPortTemplate' + ), ), migrations.AddField( model_name='devicetype', name='power_outlet_template_count', - field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.PowerOutletTemplate'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, to_field='device_type', to_model='dcim.PowerOutletTemplate' + ), ), migrations.AddField( model_name='devicetype', name='interface_template_count', - field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.InterfaceTemplate'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, to_field='device_type', to_model='dcim.InterfaceTemplate' + ), ), migrations.AddField( model_name='devicetype', name='front_port_template_count', - field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.FrontPortTemplate'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, to_field='device_type', to_model='dcim.FrontPortTemplate' + ), ), migrations.AddField( model_name='devicetype', name='rear_port_template_count', - field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.RearPortTemplate'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, to_field='device_type', to_model='dcim.RearPortTemplate' + ), ), migrations.AddField( model_name='devicetype', name='device_bay_template_count', - field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.DeviceBayTemplate'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, to_field='device_type', to_model='dcim.DeviceBayTemplate' + ), ), migrations.AddField( model_name='devicetype', name='module_bay_template_count', - field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.ModuleBayTemplate'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, to_field='device_type', to_model='dcim.ModuleBayTemplate' + ), ), migrations.AddField( model_name='devicetype', name='inventory_item_template_count', - field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.InventoryItemTemplate'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, to_field='device_type', to_model='dcim.InventoryItemTemplate' + ), ), migrations.AddField( model_name='virtualchassis', name='member_count', - field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='virtual_chassis', to_model='dcim.Device'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, to_field='virtual_chassis', to_model='dcim.Device' + ), ), migrations.AddField( model_name='interfacetemplate', @@ -241,7 +326,13 @@ class Migration(migrations.Migration): 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'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='power_feeds', + to='tenancy.tenant', + ), ), migrations.RenameField( model_name='device', diff --git a/netbox/dcim/migrations/0184_protect_child_interfaces.py b/netbox/dcim/migrations/0184_protect_child_interfaces.py index 3459e23fc..58eca506d 100644 --- a/netbox/dcim/migrations/0184_protect_child_interfaces.py +++ b/netbox/dcim/migrations/0184_protect_child_interfaces.py @@ -5,7 +5,6 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ ('dcim', '0183_devicetype_exclude_from_utilization'), ] @@ -14,6 +13,12 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='interface', name='parent', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.RESTRICT, related_name='child_interfaces', to='dcim.interface'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.RESTRICT, + related_name='child_interfaces', + to='dcim.interface', + ), ), ] diff --git a/netbox/dcim/migrations/0185_gfk_indexes.py b/netbox/dcim/migrations/0185_gfk_indexes.py index 84cdc53ff..5c099b380 100644 --- a/netbox/dcim/migrations/0185_gfk_indexes.py +++ b/netbox/dcim/migrations/0185_gfk_indexes.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('dcim', '0184_protect_child_interfaces'), ] diff --git a/netbox/dcim/migrations/0186_location_facility.py b/netbox/dcim/migrations/0186_location_facility.py index 759ee813b..3d22503b6 100644 --- a/netbox/dcim/migrations/0186_location_facility.py +++ b/netbox/dcim/migrations/0186_location_facility.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('dcim', '0185_gfk_indexes'), ] diff --git a/netbox/dcim/migrations/0187_alter_device_vc_position.py b/netbox/dcim/migrations/0187_alter_device_vc_position.py index d4a42dc20..10b636959 100644 --- a/netbox/dcim/migrations/0187_alter_device_vc_position.py +++ b/netbox/dcim/migrations/0187_alter_device_vc_position.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('dcim', '0186_location_facility'), ] diff --git a/netbox/dcim/migrations/0188_racktype.py b/netbox/dcim/migrations/0188_racktype.py index aa45246e5..a5265d030 100644 --- a/netbox/dcim/migrations/0188_racktype.py +++ b/netbox/dcim/migrations/0188_racktype.py @@ -9,7 +9,6 @@ import utilities.ordering class Migration(migrations.Migration): - dependencies = [ ('extras', '0118_customfield_uniqueness'), ('dcim', '0187_alter_device_vc_position'), @@ -22,36 +21,41 @@ class Migration(migrations.Migration): ('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=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)), - ('manufacturer', models.ForeignKey( - on_delete=django.db.models.deletion.PROTECT, - related_name='rack_types', - to='dcim.manufacturer' - )), + ( + 'manufacturer', + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, related_name='rack_types', to='dcim.manufacturer' + ), + ), ('model', models.CharField(max_length=100)), ('slug', models.SlugField(max_length=100, unique=True)), ('form_factor', models.CharField(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)] - )), + ( + '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)), diff --git a/netbox/dcim/migrations/0189_moduletype_rack_airflow.py b/netbox/dcim/migrations/0189_moduletype_rack_airflow.py index 31787b67d..c356e32f7 100644 --- a/netbox/dcim/migrations/0189_moduletype_rack_airflow.py +++ b/netbox/dcim/migrations/0189_moduletype_rack_airflow.py @@ -2,7 +2,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('dcim', '0188_racktype'), ] diff --git a/netbox/dcim/migrations/0190_nested_modules.py b/netbox/dcim/migrations/0190_nested_modules.py index 9cef40efb..239e08639 100644 --- a/netbox/dcim/migrations/0190_nested_modules.py +++ b/netbox/dcim/migrations/0190_nested_modules.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('dcim', '0189_moduletype_rack_airflow'), ('extras', '0121_customfield_related_object_filter'), @@ -34,12 +33,25 @@ class Migration(migrations.Migration): migrations.AddField( model_name='modulebay', name='module', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.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='modulebay', name='parent', - field=mptt.fields.TreeForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='dcim.modulebay'), + field=mptt.fields.TreeForeignKey( + blank=True, + editable=False, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name='children', + to='dcim.modulebay', + ), ), migrations.AddField( model_name='modulebay', @@ -56,19 +68,35 @@ class Migration(migrations.Migration): migrations.AddField( model_name='modulebaytemplate', name='module_type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name='%(class)ss', + to='dcim.moduletype', + ), ), migrations.AlterField( model_name='modulebaytemplate', name='device_type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name='%(class)ss', + to='dcim.devicetype', + ), ), migrations.AddConstraint( model_name='modulebay', - constraint=models.UniqueConstraint(fields=('device', 'module', 'name'), name='dcim_modulebay_unique_device_module_name'), + constraint=models.UniqueConstraint( + fields=('device', 'module', 'name'), name='dcim_modulebay_unique_device_module_name' + ), ), migrations.AddConstraint( model_name='modulebaytemplate', - constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_modulebaytemplate_unique_module_type_name'), + constraint=models.UniqueConstraint( + fields=('module_type', 'name'), name='dcim_modulebaytemplate_unique_module_type_name' + ), ), ] diff --git a/netbox/dcim/migrations/0191_module_bay_rebuild.py b/netbox/dcim/migrations/0191_module_bay_rebuild.py index 260063213..4f8a461f2 100644 --- a/netbox/dcim/migrations/0191_module_bay_rebuild.py +++ b/netbox/dcim/migrations/0191_module_bay_rebuild.py @@ -13,14 +13,10 @@ def rebuild_mptt(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('dcim', '0190_nested_modules'), ] operations = [ - migrations.RunPython( - code=rebuild_mptt, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=rebuild_mptt, reverse_code=migrations.RunPython.noop), ] diff --git a/netbox/dcim/migrations/0192_inventoryitem_status.py b/netbox/dcim/migrations/0192_inventoryitem_status.py index 335ab2ca7..027f2daef 100644 --- a/netbox/dcim/migrations/0192_inventoryitem_status.py +++ b/netbox/dcim/migrations/0192_inventoryitem_status.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('dcim', '0191_module_bay_rebuild'), ] diff --git a/netbox/dcim/migrations/0193_poweroutlet_color.py b/netbox/dcim/migrations/0193_poweroutlet_color.py index 0a6c08b48..f7e3c430c 100644 --- a/netbox/dcim/migrations/0193_poweroutlet_color.py +++ b/netbox/dcim/migrations/0193_poweroutlet_color.py @@ -5,7 +5,6 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ ('dcim', '0192_inventoryitem_status'), ] diff --git a/netbox/dcim/migrations/0194_charfield_null_choices.py b/netbox/dcim/migrations/0194_charfield_null_choices.py index 8e507c050..83c056386 100644 --- a/netbox/dcim/migrations/0194_charfield_null_choices.py +++ b/netbox/dcim/migrations/0194_charfield_null_choices.py @@ -69,7 +69,6 @@ def set_null_values(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('dcim', '0193_poweroutlet_color'), ] @@ -280,8 +279,5 @@ class Migration(migrations.Migration): name='cable_end', field=models.CharField(blank=True, max_length=1, null=True), ), - migrations.RunPython( - code=set_null_values, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=set_null_values, reverse_code=migrations.RunPython.noop), ] diff --git a/netbox/dcim/migrations/0195_interface_vlan_translation_policy.py b/netbox/dcim/migrations/0195_interface_vlan_translation_policy.py index 42ff1205a..9ec404886 100644 --- a/netbox/dcim/migrations/0195_interface_vlan_translation_policy.py +++ b/netbox/dcim/migrations/0195_interface_vlan_translation_policy.py @@ -5,7 +5,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('dcim', '0194_charfield_null_choices'), ('ipam', '0074_vlantranslationpolicy_vlantranslationrule'), @@ -15,6 +14,8 @@ class Migration(migrations.Migration): migrations.AddField( model_name='interface', name='vlan_translation_policy', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='ipam.vlantranslationpolicy'), + field=models.ForeignKey( + blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='ipam.vlantranslationpolicy' + ), ), ] diff --git a/netbox/dcim/migrations/0196_qinq_svlan.py b/netbox/dcim/migrations/0196_qinq_svlan.py index 9012d74f3..a03ad144a 100644 --- a/netbox/dcim/migrations/0196_qinq_svlan.py +++ b/netbox/dcim/migrations/0196_qinq_svlan.py @@ -3,7 +3,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('dcim', '0195_interface_vlan_translation_policy'), ('ipam', '0075_vlan_qinq'), @@ -13,7 +12,13 @@ class Migration(migrations.Migration): migrations.AddField( model_name='interface', name='qinq_svlan', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(class)ss_svlan', to='ipam.vlan'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name='%(class)ss_svlan', + to='ipam.vlan', + ), ), migrations.AlterField( model_name='interface', @@ -23,6 +28,12 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='interface', name='untagged_vlan', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(class)ss_as_untagged', to='ipam.vlan'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name='%(class)ss_as_untagged', + to='ipam.vlan', + ), ), ] diff --git a/netbox/dcim/migrations/0197_natural_sort_collation.py b/netbox/dcim/migrations/0197_natural_sort_collation.py index a77632b37..268bda7eb 100644 --- a/netbox/dcim/migrations/0197_natural_sort_collation.py +++ b/netbox/dcim/migrations/0197_natural_sort_collation.py @@ -3,15 +3,14 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ ('dcim', '0196_qinq_svlan'), ] operations = [ CreateCollation( - "natural_sort", - provider="icu", - locale="und-u-kn-true", + 'natural_sort', + provider='icu', + locale='und-u-kn-true', ), ] diff --git a/netbox/dcim/migrations/0198_natural_ordering.py b/netbox/dcim/migrations/0198_natural_ordering.py index 83e94a195..cf4361a2b 100644 --- a/netbox/dcim/migrations/0198_natural_ordering.py +++ b/netbox/dcim/migrations/0198_natural_ordering.py @@ -2,7 +2,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('dcim', '0197_natural_sort_collation'), ] diff --git a/netbox/dcim/migrations/0199_macaddress.py b/netbox/dcim/migrations/0199_macaddress.py index 8068c7436..ae18d5f63 100644 --- a/netbox/dcim/migrations/0199_macaddress.py +++ b/netbox/dcim/migrations/0199_macaddress.py @@ -7,7 +7,6 @@ import utilities.json class Migration(migrations.Migration): - dependencies = [ ('dcim', '0198_natural_ordering'), ('extras', '0122_charfield_null_choices'), @@ -20,17 +19,33 @@ class Migration(migrations.Migration): ('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=utilities.json.CustomFieldJSONEncoder), + ), ('description', models.CharField(blank=True, max_length=200)), ('comments', models.TextField(blank=True)), ('mac_address', dcim.fields.MACAddressField()), ('assigned_object_id', models.PositiveBigIntegerField(blank=True, null=True)), - ('assigned_object_type', 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')), + ( + 'assigned_object_type', + 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', + ), + ), ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), ], - options={ - 'abstract': False, - 'ordering': ('mac_address',) - }, + options={'abstract': False, 'ordering': ('mac_address',)}, ), ] diff --git a/netbox/dcim/migrations/0200_populate_mac_addresses.py b/netbox/dcim/migrations/0200_populate_mac_addresses.py index 1f3c5dee9..0cd18d78e 100644 --- a/netbox/dcim/migrations/0200_populate_mac_addresses.py +++ b/netbox/dcim/migrations/0200_populate_mac_addresses.py @@ -10,9 +10,7 @@ def populate_mac_addresses(apps, schema_editor): mac_addresses = [ MACAddress( - mac_address=interface.mac_address, - assigned_object_type=interface_ct, - assigned_object_id=interface.pk + mac_address=interface.mac_address, assigned_object_type=interface_ct, assigned_object_id=interface.pk ) for interface in Interface.objects.filter(mac_address__isnull=False) ] @@ -24,7 +22,6 @@ def populate_mac_addresses(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('dcim', '0199_macaddress'), ] @@ -38,13 +35,10 @@ class Migration(migrations.Migration): null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', - to='dcim.macaddress' + to='dcim.macaddress', ), ), - migrations.RunPython( - code=populate_mac_addresses, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=populate_mac_addresses, reverse_code=migrations.RunPython.noop), migrations.RemoveField( model_name='interface', name='mac_address', diff --git a/netbox/dcim/models/device_component_templates.py b/netbox/dcim/models/device_component_templates.py index ddd4d2426..b4f057711 100644 --- a/netbox/dcim/models/device_component_templates.py +++ b/netbox/dcim/models/device_component_templates.py @@ -311,7 +311,9 @@ class PowerPortTemplate(ModularComponentTemplateModel): if self.maximum_draw is not None and self.allocated_draw is not None: if self.allocated_draw > self.maximum_draw: raise ValidationError({ - 'allocated_draw': _("Allocated draw cannot exceed the maximum draw ({maximum_draw}W).").format(maximum_draw=self.maximum_draw) + 'allocated_draw': _( + "Allocated draw cannot exceed the maximum draw ({maximum_draw}W)." + ).format(maximum_draw=self.maximum_draw) }) def to_yaml(self): @@ -365,11 +367,15 @@ class PowerOutletTemplate(ModularComponentTemplateModel): if self.power_port: if self.device_type and self.power_port.device_type != self.device_type: raise ValidationError( - _("Parent power port ({power_port}) must belong to the same device type").format(power_port=self.power_port) + _("Parent power port ({power_port}) must belong to the same device type").format( + power_port=self.power_port + ) ) if self.module_type and self.power_port.module_type != self.module_type: raise ValidationError( - _("Parent power port ({power_port}) must belong to the same module type").format(power_port=self.power_port) + _("Parent power port ({power_port}) must belong to the same module type").format( + power_port=self.power_port + ) ) def instantiate(self, **kwargs): @@ -467,11 +473,15 @@ class InterfaceTemplate(ModularComponentTemplateModel): raise ValidationError({'bridge': _("An interface cannot be bridged to itself.")}) if self.device_type and self.device_type != self.bridge.device_type: raise ValidationError({ - 'bridge': _("Bridge interface ({bridge}) must belong to the same device type").format(bridge=self.bridge) + 'bridge': _( + "Bridge interface ({bridge}) must belong to the same device type" + ).format(bridge=self.bridge) }) if self.module_type and self.module_type != self.bridge.module_type: raise ValidationError({ - 'bridge': _("Bridge interface ({bridge}) must belong to the same module type").format(bridge=self.bridge) + 'bridge': _( + "Bridge interface ({bridge}) must belong to the same module type" + ).format(bridge=self.bridge) }) if self.rf_role and self.type not in WIRELESS_IFACE_TYPES: @@ -714,7 +724,9 @@ class DeviceBayTemplate(ComponentTemplateModel): def clean(self): if self.device_type and self.device_type.subdevice_role != SubdeviceRoleChoices.ROLE_PARENT: raise ValidationError( - _("Subdevice role of device type ({device_type}) must be set to \"parent\" to allow device bays.").format(device_type=self.device_type) + _( + 'Subdevice role of device type ({device_type}) must be set to "parent" to allow device bays.' + ).format(device_type=self.device_type) ) def to_yaml(self): diff --git a/netbox/dcim/models/devices.py b/netbox/dcim/models/devices.py index b49d680a3..1fbffa54b 100644 --- a/netbox/dcim/models/devices.py +++ b/netbox/dcim/models/devices.py @@ -532,7 +532,10 @@ def update_interface_bridges(device, interface_templates, module=None): interface = Interface.objects.get(device=device, name=interface_template.resolve_name(module=module)) if interface_template.bridge: - interface.bridge = Interface.objects.get(device=device, name=interface_template.bridge.resolve_name(module=module)) + interface.bridge = Interface.objects.get( + device=device, + name=interface_template.bridge.resolve_name(module=module) + ) interface.full_clean() interface.save() @@ -909,7 +912,10 @@ class Device( }) if self.primary_ip4.assigned_object in vc_interfaces: pass - elif self.primary_ip4.nat_inside is not None and self.primary_ip4.nat_inside.assigned_object in vc_interfaces: + elif ( + self.primary_ip4.nat_inside is not None and + self.primary_ip4.nat_inside.assigned_object in vc_interfaces + ): pass else: raise ValidationError({ @@ -924,7 +930,10 @@ class Device( }) if self.primary_ip6.assigned_object in vc_interfaces: pass - elif self.primary_ip6.nat_inside is not None and self.primary_ip6.nat_inside.assigned_object in vc_interfaces: + elif ( + self.primary_ip6.nat_inside is not None and + self.primary_ip6.nat_inside.assigned_object in vc_interfaces + ): pass else: raise ValidationError({ @@ -978,9 +987,10 @@ class Device( if hasattr(self, 'vc_master_for') and self.vc_master_for and self.vc_master_for != self.virtual_chassis: raise ValidationError({ - 'virtual_chassis': _('Device cannot be removed from virtual chassis {virtual_chassis} because it is currently designated as its master.').format( - virtual_chassis=self.vc_master_for - ) + 'virtual_chassis': _( + 'Device cannot be removed from virtual chassis {virtual_chassis} because it is currently ' + 'designated as its master.' + ).format(virtual_chassis=self.vc_master_for) }) def _instantiate_components(self, queryset, bulk_create=True): diff --git a/netbox/dcim/models/racks.py b/netbox/dcim/models/racks.py index 08b7f5a35..78eb0ea4a 100644 --- a/netbox/dcim/models/racks.py +++ b/netbox/dcim/models/racks.py @@ -379,7 +379,9 @@ class Rack(ContactsMixin, ImageAttachmentsMixin, RackBase): min_height = top_device.position + top_device.device_type.u_height - self.starting_unit if self.u_height < min_height: raise ValidationError({ - 'u_height': _("Rack must be at least {min_height}U tall to house currently installed devices.").format(min_height=min_height) + 'u_height': _( + "Rack must be at least {min_height}U tall to house currently installed devices." + ).format(min_height=min_height) }) # Validate that the Rack's starting unit is less than or equal to the position of the lowest mounted Device diff --git a/netbox/dcim/svg/racks.py b/netbox/dcim/svg/racks.py index 0f73095b5..81f8ad3a5 100644 --- a/netbox/dcim/svg/racks.py +++ b/netbox/dcim/svg/racks.py @@ -153,7 +153,10 @@ class RackElevationSVG: if self.rack.desc_units: y += int((position - self.rack.starting_unit) * self.unit_height) else: - y += int((self.rack.u_height - position + self.rack.starting_unit) * self.unit_height) - int(height * self.unit_height) + y += ( + int((self.rack.u_height - position + self.rack.starting_unit) * self.unit_height) - + int(height * self.unit_height) + ) return x, y diff --git a/netbox/dcim/tables/devices.py b/netbox/dcim/tables/devices.py index 494d83114..59d0845d5 100644 --- a/netbox/dcim/tables/devices.py +++ b/netbox/dcim/tables/devices.py @@ -391,7 +391,8 @@ class ConsolePortTable(ModularDeviceComponentTable, PathEndpointTable): model = models.ConsolePort fields = ( 'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'type', 'speed', 'description', - 'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'inventory_items', 'tags', 'created', 'last_updated', + 'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'inventory_items', 'tags', 'created', + 'last_updated', ) default_columns = ('pk', 'name', 'device', 'label', 'type', 'speed', 'description') @@ -431,7 +432,8 @@ class ConsoleServerPortTable(ModularDeviceComponentTable, PathEndpointTable): model = models.ConsoleServerPort fields = ( 'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'type', 'speed', 'description', - 'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'inventory_items', 'tags', 'created', 'last_updated', + 'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'inventory_items', 'tags', 'created', + 'last_updated', ) default_columns = ('pk', 'name', 'device', 'label', 'type', 'speed', 'description') @@ -987,8 +989,8 @@ class InventoryItemTable(DeviceComponentTable): class Meta(NetBoxTable.Meta): model = models.InventoryItem fields = ( - 'pk', 'id', 'name', 'device', 'parent', 'component', 'label', 'status', 'role', 'manufacturer', 'part_id', 'serial', - 'asset_tag', 'description', 'discovered', 'tags', 'created', 'last_updated', + 'pk', 'id', 'name', 'device', 'parent', 'component', 'label', 'status', 'role', 'manufacturer', 'part_id', + 'serial', 'asset_tag', 'description', 'discovered', 'tags', 'created', 'last_updated', ) default_columns = ( 'pk', 'name', 'device', 'label', 'status', 'role', 'manufacturer', 'part_id', 'serial', 'asset_tag', @@ -1006,8 +1008,8 @@ class DeviceInventoryItemTable(InventoryItemTable): class Meta(NetBoxTable.Meta): model = models.InventoryItem fields = ( - 'pk', 'id', 'name', 'label', 'status', 'role', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'component', - 'description', 'discovered', 'tags', 'actions', + 'pk', 'id', 'name', 'label', 'status', 'role', 'manufacturer', 'part_id', 'serial', 'asset_tag', + 'component', 'description', 'discovered', 'tags', 'actions', ) default_columns = ( 'pk', 'name', 'label', 'status', 'role', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'component', diff --git a/netbox/dcim/tests/test_api.py b/netbox/dcim/tests/test_api.py index f78722b67..c273e02dd 100644 --- a/netbox/dcim/tests/test_api.py +++ b/netbox/dcim/tests/test_api.py @@ -205,13 +205,41 @@ class LocationTest(APIViewTestCases.APIViewTestCase): Site.objects.bulk_create(sites) parent_locations = ( - Location.objects.create(site=sites[0], name='Parent Location 1', slug='parent-location-1', status=LocationStatusChoices.STATUS_ACTIVE), - Location.objects.create(site=sites[1], name='Parent Location 2', slug='parent-location-2', status=LocationStatusChoices.STATUS_ACTIVE), + Location.objects.create( + site=sites[0], + name='Parent Location 1', + slug='parent-location-1', + status=LocationStatusChoices.STATUS_ACTIVE, + ), + Location.objects.create( + site=sites[1], + name='Parent Location 2', + slug='parent-location-2', + status=LocationStatusChoices.STATUS_ACTIVE, + ), ) - Location.objects.create(site=sites[0], name='Location 1', slug='location-1', parent=parent_locations[0], status=LocationStatusChoices.STATUS_ACTIVE) - Location.objects.create(site=sites[0], name='Location 2', slug='location-2', parent=parent_locations[0], status=LocationStatusChoices.STATUS_ACTIVE) - Location.objects.create(site=sites[0], name='Location 3', slug='location-3', parent=parent_locations[0], status=LocationStatusChoices.STATUS_ACTIVE) + Location.objects.create( + site=sites[0], + name='Location 1', + slug='location-1', + parent=parent_locations[0], + status=LocationStatusChoices.STATUS_ACTIVE, + ) + Location.objects.create( + site=sites[0], + name='Location 2', + slug='location-2', + parent=parent_locations[0], + status=LocationStatusChoices.STATUS_ACTIVE, + ) + Location.objects.create( + site=sites[0], + name='Location 3', + slug='location-3', + parent=parent_locations[0], + status=LocationStatusChoices.STATUS_ACTIVE, + ) cls.create_data = [ { @@ -290,9 +318,24 @@ class RackTypeTest(APIViewTestCases.APIViewTestCase): Manufacturer.objects.bulk_create(manufacturers) rack_types = ( - RackType(manufacturer=manufacturers[0], model='Rack Type 1', slug='rack-type-1', form_factor=RackFormFactorChoices.TYPE_CABINET,), - RackType(manufacturer=manufacturers[0], model='Rack Type 2', slug='rack-type-2', form_factor=RackFormFactorChoices.TYPE_CABINET,), - RackType(manufacturer=manufacturers[0], model='Rack Type 3', slug='rack-type-3', form_factor=RackFormFactorChoices.TYPE_CABINET,), + RackType( + manufacturer=manufacturers[0], + model='Rack Type 1', + slug='rack-type-1', + form_factor=RackFormFactorChoices.TYPE_CABINET, + ), + RackType( + manufacturer=manufacturers[0], + model='Rack Type 2', + slug='rack-type-2', + form_factor=RackFormFactorChoices.TYPE_CABINET, + ), + RackType( + manufacturer=manufacturers[0], + model='Rack Type 3', + slug='rack-type-3', + form_factor=RackFormFactorChoices.TYPE_CABINET, + ), ) RackType.objects.bulk_create(rack_types) @@ -1050,10 +1093,18 @@ class InventoryItemTemplateTest(APIViewTestCases.APIViewTestCase): role = InventoryItemRole.objects.create(name='Inventory Item Role 1', slug='inventory-item-role-1') inventory_item_templates = ( - InventoryItemTemplate(device_type=devicetype, name='Inventory Item Template 1', manufacturer=manufacturer, role=role), - InventoryItemTemplate(device_type=devicetype, name='Inventory Item Template 2', manufacturer=manufacturer, role=role), - InventoryItemTemplate(device_type=devicetype, name='Inventory Item Template 3', manufacturer=manufacturer, role=role), - InventoryItemTemplate(device_type=devicetype, name='Inventory Item Template 4', manufacturer=manufacturer, role=role), + InventoryItemTemplate( + device_type=devicetype, name='Inventory Item Template 1', manufacturer=manufacturer, role=role + ), + InventoryItemTemplate( + device_type=devicetype, name='Inventory Item Template 2', manufacturer=manufacturer, role=role + ), + InventoryItemTemplate( + device_type=devicetype, name='Inventory Item Template 3', manufacturer=manufacturer, role=role + ), + InventoryItemTemplate( + device_type=devicetype, name='Inventory Item Template 4', manufacturer=manufacturer, role=role + ), ) for item in inventory_item_templates: item.save() @@ -1961,9 +2012,15 @@ class InventoryItemTest(APIViewTestCases.APIViewTestCase): ) Interface.objects.bulk_create(interfaces) - InventoryItem.objects.create(device=device, name='Inventory Item 1', role=roles[0], manufacturer=manufacturer, component=interfaces[0]) - InventoryItem.objects.create(device=device, name='Inventory Item 2', role=roles[0], manufacturer=manufacturer, component=interfaces[1]) - InventoryItem.objects.create(device=device, name='Inventory Item 3', role=roles[0], manufacturer=manufacturer, component=interfaces[2]) + InventoryItem.objects.create( + device=device, name='Inventory Item 1', role=roles[0], manufacturer=manufacturer, component=interfaces[0] + ) + InventoryItem.objects.create( + device=device, name='Inventory Item 2', role=roles[0], manufacturer=manufacturer, component=interfaces[1] + ) + InventoryItem.objects.create( + device=device, name='Inventory Item 3', role=roles[0], manufacturer=manufacturer, component=interfaces[2] + ) cls.create_data = [ { diff --git a/netbox/dcim/tests/test_cablepaths.py b/netbox/dcim/tests/test_cablepaths.py index b504d389a..1acc9a8a1 100644 --- a/netbox/dcim/tests/test_cablepaths.py +++ b/netbox/dcim/tests/test_cablepaths.py @@ -661,24 +661,64 @@ class CablePathTestCase(TestCase): ) cable5.save() path1 = self.assertPathExists( - ([interface1, interface2], cable1, frontport1_1, rearport1, cable3, rearport2, frontport2_1, cable4, [interface5, interface6]), + ( + [interface1, interface2], + cable1, + frontport1_1, + rearport1, + cable3, + rearport2, + frontport2_1, + cable4, + [interface5, interface6], + ), is_complete=True, - is_active=True + is_active=True, ) path2 = self.assertPathExists( - ([interface3, interface4], cable2, frontport1_2, rearport1, cable3, rearport2, frontport2_2, cable5, [interface7, interface8]), + ( + [interface3, interface4], + cable2, + frontport1_2, + rearport1, + cable3, + rearport2, + frontport2_2, + cable5, + [interface7, interface8], + ), is_complete=True, - is_active=True + is_active=True, ) path3 = self.assertPathExists( - ([interface5, interface6], cable4, frontport2_1, rearport2, cable3, rearport1, frontport1_1, cable1, [interface1, interface2]), + ( + [interface5, interface6], + cable4, + frontport2_1, + rearport2, + cable3, + rearport1, + frontport1_1, + cable1, + [interface1, interface2], + ), is_complete=True, - is_active=True + is_active=True, ) path4 = self.assertPathExists( - ([interface7, interface8], cable5, frontport2_2, rearport2, cable3, rearport1, frontport1_2, cable2, [interface3, interface4]), + ( + [interface7, interface8], + cable5, + frontport2_2, + rearport2, + cable3, + rearport1, + frontport1_2, + cable2, + [interface3, interface4], + ), is_complete=True, - is_active=True + is_active=True, ) self.assertEqual(CablePath.objects.count(), 4) @@ -1167,7 +1207,11 @@ class CablePathTestCase(TestCase): [IF1] --C1-- [CT1] """ interface1 = Interface.objects.create(device=self.device, name='Interface 1') - circuittermination1 = CircuitTermination.objects.create(circuit=self.circuit, termination=self.site, term_side='A') + circuittermination1 = CircuitTermination.objects.create( + circuit=self.circuit, + termination=self.site, + term_side='A' + ) # Create cable 1 cable1 = Cable( @@ -1198,7 +1242,11 @@ class CablePathTestCase(TestCase): """ interface1 = Interface.objects.create(device=self.device, name='Interface 1') interface2 = Interface.objects.create(device=self.device, name='Interface 2') - circuittermination1 = CircuitTermination.objects.create(circuit=self.circuit, termination=self.site, term_side='A') + circuittermination1 = CircuitTermination.objects.create( + circuit=self.circuit, + termination=self.site, + term_side='A' + ) # Create cable 1 cable1 = Cable( @@ -1214,7 +1262,11 @@ class CablePathTestCase(TestCase): ) # Create CT2 - circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, termination=self.site, term_side='Z') + circuittermination2 = CircuitTermination.objects.create( + circuit=self.circuit, + termination=self.site, + term_side='Z' + ) # Check for partial path to site self.assertPathExists( @@ -1266,7 +1318,11 @@ class CablePathTestCase(TestCase): interface2 = Interface.objects.create(device=self.device, name='Interface 2') interface3 = Interface.objects.create(device=self.device, name='Interface 3') interface4 = Interface.objects.create(device=self.device, name='Interface 4') - circuittermination1 = CircuitTermination.objects.create(circuit=self.circuit, termination=self.site, term_side='A') + circuittermination1 = CircuitTermination.objects.create( + circuit=self.circuit, + termination=self.site, + term_side='A' + ) # Create cable 1 cable1 = Cable( @@ -1282,7 +1338,11 @@ class CablePathTestCase(TestCase): ) # Create CT2 - circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, termination=self.site, term_side='Z') + circuittermination2 = CircuitTermination.objects.create( + circuit=self.circuit, + termination=self.site, + term_side='Z' + ) # Check for partial path to site self.assertPathExists( @@ -1299,14 +1359,28 @@ class CablePathTestCase(TestCase): # Check for complete path in each direction self.assertPathExists( - ([interface1, interface2], cable1, circuittermination1, circuittermination2, cable2, [interface3, interface4]), + ( + [interface1, interface2], + cable1, + circuittermination1, + circuittermination2, + cable2, + [interface3, interface4], + ), is_complete=True, - is_active=True + is_active=True, ) self.assertPathExists( - ([interface3, interface4], cable2, circuittermination2, circuittermination1, cable1, [interface1, interface2]), + ( + [interface3, interface4], + cable2, + circuittermination2, + circuittermination1, + cable1, + [interface1, interface2], + ), is_complete=True, - is_active=True + is_active=True, ) self.assertEqual(CablePath.objects.count(), 2) @@ -1335,8 +1409,16 @@ class CablePathTestCase(TestCase): """ interface1 = Interface.objects.create(device=self.device, name='Interface 1') site2 = Site.objects.create(name='Site 2', slug='site-2') - circuittermination1 = CircuitTermination.objects.create(circuit=self.circuit, termination=self.site, term_side='A') - circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, termination=site2, term_side='Z') + circuittermination1 = CircuitTermination.objects.create( + circuit=self.circuit, + termination=self.site, + term_side='A' + ) + circuittermination2 = CircuitTermination.objects.create( + circuit=self.circuit, + termination=site2, + term_side='Z' + ) # Create cable 1 cable1 = Cable( @@ -1365,8 +1447,16 @@ class CablePathTestCase(TestCase): """ interface1 = Interface.objects.create(device=self.device, name='Interface 1') providernetwork = ProviderNetwork.objects.create(name='Provider Network 1', provider=self.circuit.provider) - circuittermination1 = CircuitTermination.objects.create(circuit=self.circuit, termination=self.site, term_side='A') - circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, termination=providernetwork, term_side='Z') + circuittermination1 = CircuitTermination.objects.create( + circuit=self.circuit, + termination=self.site, + term_side='A' + ) + circuittermination2 = CircuitTermination.objects.create( + circuit=self.circuit, + termination=providernetwork, + term_side='Z' + ) # Create cable 1 cable1 = Cable( @@ -1413,8 +1503,15 @@ class CablePathTestCase(TestCase): frontport2_2 = FrontPort.objects.create( device=self.device, name='Front Port 2:2', rear_port=rearport2, rear_port_position=2 ) - circuittermination1 = CircuitTermination.objects.create(circuit=self.circuit, termination=self.site, term_side='A') - circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, termination=self.site, term_side='Z') + circuittermination1 = CircuitTermination.objects.create( + circuit=self.circuit, + termination=self.site, + term_side='A' + ) + circuittermination2 = CircuitTermination.objects.create( + circuit=self.circuit, + termination=self.site, term_side='Z' + ) # Create cables cable1 = Cable( @@ -1499,10 +1596,26 @@ class CablePathTestCase(TestCase): interface1 = Interface.objects.create(device=self.device, name='Interface 1') interface2 = Interface.objects.create(device=self.device, name='Interface 2') circuit2 = Circuit.objects.create(provider=self.circuit.provider, type=self.circuit.type, cid='Circuit 2') - circuittermination1 = CircuitTermination.objects.create(circuit=self.circuit, termination=self.site, term_side='A') - circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, termination=self.site, term_side='Z') - circuittermination3 = CircuitTermination.objects.create(circuit=circuit2, termination=self.site, term_side='A') - circuittermination4 = CircuitTermination.objects.create(circuit=circuit2, termination=self.site, term_side='Z') + circuittermination1 = CircuitTermination.objects.create( + circuit=self.circuit, + termination=self.site, + term_side='A' + ) + circuittermination2 = CircuitTermination.objects.create( + circuit=self.circuit, + termination=self.site, + term_side='Z' + ) + circuittermination3 = CircuitTermination.objects.create( + circuit=circuit2, + termination=self.site, + term_side='A' + ) + circuittermination4 = CircuitTermination.objects.create( + circuit=circuit2, + termination=self.site, + term_side='Z' + ) # Create cables cable1 = Cable( @@ -1706,45 +1819,95 @@ class CablePathTestCase(TestCase): ) cable3.save() self.assertPathExists( - (interface1, cable1, (frontport1_1, frontport1_2), rearport1, cable3, rearport2, (frontport2_1, frontport2_2)), - is_complete=False + ( + interface1, + cable1, + (frontport1_1, frontport1_2), + rearport1, + cable3, + rearport2, + (frontport2_1, frontport2_2), + ), + is_complete=False, ) self.assertPathExists( - (interface2, cable2, (frontport1_3, frontport1_4), rearport1, cable3, rearport2, (frontport2_3, frontport2_4)), - is_complete=False + ( + interface2, + cable2, + (frontport1_3, frontport1_4), + rearport1, + cable3, + rearport2, + (frontport2_3, frontport2_4), + ), + is_complete=False, ) self.assertEqual(CablePath.objects.count(), 2) # Create cables 4-5 - cable4 = Cable( - a_terminations=[frontport2_1, frontport2_2], - b_terminations=[interface3] - ) + cable4 = Cable(a_terminations=[frontport2_1, frontport2_2], b_terminations=[interface3]) cable4.save() - cable5 = Cable( - a_terminations=[frontport2_3, frontport2_4], - b_terminations=[interface4] - ) + cable5 = Cable(a_terminations=[frontport2_3, frontport2_4], b_terminations=[interface4]) cable5.save() path1 = self.assertPathExists( - (interface1, cable1, (frontport1_1, frontport1_2), rearport1, cable3, rearport2, (frontport2_1, frontport2_2), cable4, interface3), + ( + interface1, + cable1, + (frontport1_1, frontport1_2), + rearport1, + cable3, + rearport2, + (frontport2_1, frontport2_2), + cable4, + interface3, + ), is_complete=True, - is_active=True + is_active=True, ) path2 = self.assertPathExists( - (interface2, cable2, (frontport1_3, frontport1_4), rearport1, cable3, rearport2, (frontport2_3, frontport2_4), cable5, interface4), + ( + interface2, + cable2, + (frontport1_3, frontport1_4), + rearport1, + cable3, + rearport2, + (frontport2_3, frontport2_4), + cable5, + interface4, + ), is_complete=True, - is_active=True + is_active=True, ) path3 = self.assertPathExists( - (interface3, cable4, (frontport2_1, frontport2_2), rearport2, cable3, rearport1, (frontport1_1, frontport1_2), cable1, interface1), + ( + interface3, + cable4, + (frontport2_1, frontport2_2), + rearport2, + cable3, + rearport1, + (frontport1_1, frontport1_2), + cable1, + interface1, + ), is_complete=True, - is_active=True + is_active=True, ) path4 = self.assertPathExists( - (interface4, cable5, (frontport2_3, frontport2_4), rearport2, cable3, rearport1, (frontport1_3, frontport1_4), cable2, interface2), + ( + interface4, + cable5, + (frontport2_3, frontport2_4), + rearport2, + cable3, + rearport1, + (frontport1_3, frontport1_4), + cable2, + interface2, + ), is_complete=True, - is_active=True + is_active=True, ) self.assertEqual(CablePath.objects.count(), 4) @@ -1809,7 +1972,10 @@ class CablePathTestCase(TestCase): ) cable1.save() self.assertPathExists( - (interface1, cable1, (frontport1, frontport3), (rearport1, rearport3), (cable2, cable4), (rearport2, rearport4), (frontport2, frontport4)), + ( + interface1, cable1, (frontport1, frontport3), (rearport1, rearport3), (cable2, cable4), + (rearport2, rearport4), (frontport2, frontport4) + ), is_complete=False ) self.assertEqual(CablePath.objects.count(), 1) diff --git a/netbox/dcim/tests/test_filtersets.py b/netbox/dcim/tests/test_filtersets.py index 897612b84..ede1e2a09 100644 --- a/netbox/dcim/tests/test_filtersets.py +++ b/netbox/dcim/tests/test_filtersets.py @@ -243,9 +243,41 @@ class SiteTestCase(TestCase, ChangeLoggedFilterSetTests): ASN.objects.bulk_create(asns) sites = ( - Site(name='Site 1', slug='site-1', region=regions[0], group=groups[0], tenant=tenants[0], status=SiteStatusChoices.STATUS_ACTIVE, facility='Facility 1', latitude=10, longitude=10, description='foobar1'), - Site(name='Site 2', slug='site-2', region=regions[1], group=groups[1], tenant=tenants[1], status=SiteStatusChoices.STATUS_PLANNED, facility='Facility 2', latitude=20, longitude=20, description='foobar2'), - Site(name='Site 3', slug='site-3', region=regions[2], group=groups[2], tenant=tenants[2], status=SiteStatusChoices.STATUS_RETIRED, facility='Facility 3', latitude=30, longitude=30), + Site( + name='Site 1', + slug='site-1', + region=regions[0], + group=groups[0], + tenant=tenants[0], + status=SiteStatusChoices.STATUS_ACTIVE, + facility='Facility 1', + latitude=10, + longitude=10, + description='foobar1', + ), + Site( + name='Site 2', + slug='site-2', + region=regions[1], + group=groups[1], + tenant=tenants[1], + status=SiteStatusChoices.STATUS_PLANNED, + facility='Facility 2', + latitude=20, + longitude=20, + description='foobar2', + ), + Site( + name='Site 3', + slug='site-3', + region=regions[2], + group=groups[2], + tenant=tenants[2], + status=SiteStatusChoices.STATUS_RETIRED, + facility='Facility 3', + latitude=30, + longitude=30, + ), ) Site.objects.bulk_create(sites) sites[0].asns.set([asns[0]]) @@ -361,9 +393,33 @@ class LocationTestCase(TestCase, ChangeLoggedFilterSetTests): location.save() locations = ( - Location(name='Location 1A', slug='location-1a', site=sites[0], parent=parent_locations[0], status=LocationStatusChoices.STATUS_PLANNED, facility='Facility 1', description='foobar1'), - Location(name='Location 2A', slug='location-2a', site=sites[1], parent=parent_locations[1], status=LocationStatusChoices.STATUS_STAGING, facility='Facility 2', description='foobar2'), - Location(name='Location 3A', slug='location-3a', site=sites[2], parent=parent_locations[2], status=LocationStatusChoices.STATUS_DECOMMISSIONING, facility='Facility 3', description='foobar3'), + Location( + name='Location 1A', + slug='location-1a', + site=sites[0], + parent=parent_locations[0], + status=LocationStatusChoices.STATUS_PLANNED, + facility='Facility 1', + description='foobar1', + ), + Location( + name='Location 2A', + slug='location-2a', + site=sites[1], + parent=parent_locations[1], + status=LocationStatusChoices.STATUS_STAGING, + facility='Facility 2', + description='foobar2', + ), + Location( + name='Location 3A', + slug='location-3a', + site=sites[2], + parent=parent_locations[2], + status=LocationStatusChoices.STATUS_DECOMMISSIONING, + facility='Facility 3', + description='foobar3', + ), ) for location in locations: location.save() @@ -1222,10 +1278,22 @@ class DeviceTypeTestCase(TestCase, ChangeLoggedFilterSetTests): RearPortTemplate(device_type=device_types[1], name='Rear Port 2', type=PortTypeChoices.TYPE_8P8C), ) RearPortTemplate.objects.bulk_create(rear_ports) - FrontPortTemplate.objects.bulk_create(( - FrontPortTemplate(device_type=device_types[0], name='Front Port 1', type=PortTypeChoices.TYPE_8P8C, rear_port=rear_ports[0]), - FrontPortTemplate(device_type=device_types[1], name='Front Port 2', type=PortTypeChoices.TYPE_8P8C, rear_port=rear_ports[1]), - )) + FrontPortTemplate.objects.bulk_create( + ( + FrontPortTemplate( + device_type=device_types[0], + name='Front Port 1', + type=PortTypeChoices.TYPE_8P8C, + rear_port=rear_ports[0], + ), + FrontPortTemplate( + device_type=device_types[1], + name='Front Port 2', + type=PortTypeChoices.TYPE_8P8C, + rear_port=rear_ports[1], + ), + ) + ) ModuleBayTemplate.objects.bulk_create(( ModuleBayTemplate(device_type=device_types[0], name='Module Bay 1'), ModuleBayTemplate(device_type=device_types[1], name='Module Bay 2'), @@ -1435,10 +1503,22 @@ class ModuleTypeTestCase(TestCase, ChangeLoggedFilterSetTests): RearPortTemplate(module_type=module_types[1], name='Rear Port 2', type=PortTypeChoices.TYPE_8P8C), ) RearPortTemplate.objects.bulk_create(rear_ports) - FrontPortTemplate.objects.bulk_create(( - FrontPortTemplate(module_type=module_types[0], name='Front Port 1', type=PortTypeChoices.TYPE_8P8C, rear_port=rear_ports[0]), - FrontPortTemplate(module_type=module_types[1], name='Front Port 2', type=PortTypeChoices.TYPE_8P8C, rear_port=rear_ports[1]), - )) + FrontPortTemplate.objects.bulk_create( + ( + FrontPortTemplate( + module_type=module_types[0], + name='Front Port 1', + type=PortTypeChoices.TYPE_8P8C, + rear_port=rear_ports[0], + ), + FrontPortTemplate( + module_type=module_types[1], + name='Front Port 2', + type=PortTypeChoices.TYPE_8P8C, + rear_port=rear_ports[1], + ), + ) + ) def test_q(self): params = {'q': 'foobar1'} @@ -1893,11 +1973,19 @@ class ModuleBayTemplateTestCase(TestCase, DeviceComponentTemplateFilterSetTests, ) ModuleType.objects.bulk_create(module_types) - ModuleBayTemplate.objects.bulk_create(( - ModuleBayTemplate(device_type=device_types[0], name='Module Bay 1', description='foobar1'), - ModuleBayTemplate(device_type=device_types[1], name='Module Bay 2', description='foobar2', module_type=module_types[0]), - ModuleBayTemplate(device_type=device_types[2], name='Module Bay 3', description='foobar3', module_type=module_types[1]), - )) + ModuleBayTemplate.objects.bulk_create( + ( + ModuleBayTemplate( + device_type=device_types[0], name='Module Bay 1', description='foobar1' + ), + ModuleBayTemplate( + device_type=device_types[1], name='Module Bay 2', description='foobar2', module_type=module_types[0] + ), + ModuleBayTemplate( + device_type=device_types[2], name='Module Bay 3', description='foobar3', module_type=module_types[1] + ), + ) + ) def test_name(self): params = {'name': ['Module Bay 1', 'Module Bay 2']} @@ -1996,9 +2084,15 @@ class InventoryItemTemplateTestCase(TestCase, DeviceComponentTemplateFilterSetTe item.save() child_inventory_item_templates = ( - InventoryItemTemplate(device_type=device_types[0], name='Inventory Item 1A', parent=inventory_item_templates[0]), - InventoryItemTemplate(device_type=device_types[1], name='Inventory Item 2A', parent=inventory_item_templates[1]), - InventoryItemTemplate(device_type=device_types[2], name='Inventory Item 3A', parent=inventory_item_templates[2]), + InventoryItemTemplate( + device_type=device_types[0], name='Inventory Item 1A', parent=inventory_item_templates[0] + ), + InventoryItemTemplate( + device_type=device_types[1], name='Inventory Item 2A', parent=inventory_item_templates[1] + ), + InventoryItemTemplate( + device_type=device_types[2], name='Inventory Item 3A', parent=inventory_item_templates[2] + ), ) for item in child_inventory_item_templates: item.save() @@ -2848,10 +2942,41 @@ class ConsolePortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedF Rack.objects.bulk_create(racks) devices = ( - Device(name='Device 1', device_type=device_types[0], role=roles[0], site=sites[0], location=locations[0], rack=racks[0], status='active'), - Device(name='Device 2', device_type=device_types[1], role=roles[1], site=sites[1], location=locations[1], rack=racks[1], status='planned'), - Device(name='Device 3', device_type=device_types[2], role=roles[2], site=sites[2], location=locations[2], rack=racks[2], status='offline'), - Device(name=None, device_type=device_types[0], role=roles[0], site=sites[3], status='offline'), # For cable connections + Device( + name='Device 1', + device_type=device_types[0], + role=roles[0], + site=sites[0], + location=locations[0], + rack=racks[0], + status='active', + ), + Device( + name='Device 2', + device_type=device_types[1], + role=roles[1], + site=sites[1], + location=locations[1], + rack=racks[1], + status='planned', + ), + Device( + name='Device 3', + device_type=device_types[2], + role=roles[2], + site=sites[2], + location=locations[2], + rack=racks[2], + status='offline', + ), + # For cable connections + Device( + name=None, + device_type=device_types[0], + role=roles[0], + site=sites[3], + status='offline' + ), ) Device.objects.bulk_create(devices) @@ -3029,10 +3154,41 @@ class ConsoleServerPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeL Rack.objects.bulk_create(racks) devices = ( - Device(name='Device 1', device_type=device_types[0], role=roles[0], site=sites[0], location=locations[0], rack=racks[0], status='active'), - Device(name='Device 2', device_type=device_types[1], role=roles[1], site=sites[1], location=locations[1], rack=racks[1], status='planned'), - Device(name='Device 3', device_type=device_types[2], role=roles[2], site=sites[2], location=locations[2], rack=racks[2], status='offline'), - Device(name=None, device_type=device_types[2], role=roles[2], site=sites[3], status='offline'), # For cable connections + Device( + name='Device 1', + device_type=device_types[0], + role=roles[0], + site=sites[0], + location=locations[0], + rack=racks[0], + status='active', + ), + Device( + name='Device 2', + device_type=device_types[1], + role=roles[1], + site=sites[1], + location=locations[1], + rack=racks[1], + status='planned', + ), + Device( + name='Device 3', + device_type=device_types[2], + role=roles[2], + site=sites[2], + location=locations[2], + rack=racks[2], + status='offline', + ), + # For cable connections + Device( + name=None, + device_type=device_types[2], + role=roles[2], + site=sites[3], + status='offline' + ), ) Device.objects.bulk_create(devices) @@ -3058,9 +3214,15 @@ class ConsoleServerPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeL ConsolePort.objects.bulk_create(console_ports) console_server_ports = ( - ConsoleServerPort(device=devices[0], module=modules[0], name='Console Server Port 1', label='A', description='First'), - ConsoleServerPort(device=devices[1], module=modules[1], name='Console Server Port 2', label='B', description='Second'), - ConsoleServerPort(device=devices[2], module=modules[2], name='Console Server Port 3', label='C', description='Third'), + ConsoleServerPort( + device=devices[0], module=modules[0], name='Console Server Port 1', label='A', description='First' + ), + ConsoleServerPort( + device=devices[1], module=modules[1], name='Console Server Port 2', label='B', description='Second' + ), + ConsoleServerPort( + device=devices[2], module=modules[2], name='Console Server Port 3', label='C', description='Third' + ), ) ConsoleServerPort.objects.bulk_create(console_server_ports) @@ -3210,10 +3372,41 @@ class PowerPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil Rack.objects.bulk_create(racks) devices = ( - Device(name='Device 1', device_type=device_types[0], role=roles[0], site=sites[0], location=locations[0], rack=racks[0], status='active'), - Device(name='Device 2', device_type=device_types[1], role=roles[1], site=sites[1], location=locations[1], rack=racks[1], status='planned'), - Device(name='Device 3', device_type=device_types[2], role=roles[2], site=sites[2], location=locations[2], rack=racks[2], status='offline'), - Device(name=None, device_type=device_types[2], role=roles[2], site=sites[3], status='offline'), # For cable connections + Device( + name='Device 1', + device_type=device_types[0], + role=roles[0], + site=sites[0], + location=locations[0], + rack=racks[0], + status='active', + ), + Device( + name='Device 2', + device_type=device_types[1], + role=roles[1], + site=sites[1], + location=locations[1], + rack=racks[1], + status='planned', + ), + Device( + name='Device 3', + device_type=device_types[2], + role=roles[2], + site=sites[2], + location=locations[2], + rack=racks[2], + status='offline', + ), + # For cable connections + Device( + name=None, + device_type=device_types[2], + role=roles[2], + site=sites[3], + status='offline' + ), ) Device.objects.bulk_create(devices) @@ -3239,9 +3432,33 @@ class PowerPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil PowerOutlet.objects.bulk_create(power_outlets) power_ports = ( - PowerPort(device=devices[0], module=modules[0], name='Power Port 1', label='A', maximum_draw=100, allocated_draw=50, description='First'), - PowerPort(device=devices[1], module=modules[1], name='Power Port 2', label='B', maximum_draw=200, allocated_draw=100, description='Second'), - PowerPort(device=devices[2], module=modules[2], name='Power Port 3', label='C', maximum_draw=300, allocated_draw=150, description='Third'), + PowerPort( + device=devices[0], + module=modules[0], + name='Power Port 1', + label='A', + maximum_draw=100, + allocated_draw=50, + description='First', + ), + PowerPort( + device=devices[1], + module=modules[1], + name='Power Port 2', + label='B', + maximum_draw=200, + allocated_draw=100, + description='Second', + ), + PowerPort( + device=devices[2], + module=modules[2], + name='Power Port 3', + label='C', + maximum_draw=300, + allocated_draw=150, + description='Third', + ), ) PowerPort.objects.bulk_create(power_ports) @@ -3399,10 +3616,41 @@ class PowerOutletTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedF Rack.objects.bulk_create(racks) devices = ( - Device(name='Device 1', device_type=device_types[0], role=roles[0], site=sites[0], location=locations[0], rack=racks[0], status='active'), - Device(name='Device 2', device_type=device_types[1], role=roles[1], site=sites[1], location=locations[1], rack=racks[1], status='planned'), - Device(name='Device 3', device_type=device_types[2], role=roles[2], site=sites[2], location=locations[2], rack=racks[2], status='offline'), - Device(name=None, device_type=device_types[2], role=roles[2], site=sites[3], status='offline'), # For cable connections + Device( + name='Device 1', + device_type=device_types[0], + role=roles[0], + site=sites[0], + location=locations[0], + rack=racks[0], + status='active', + ), + Device( + name='Device 2', + device_type=device_types[1], + role=roles[1], + site=sites[1], + location=locations[1], + rack=racks[1], + status='planned', + ), + Device( + name='Device 3', + device_type=device_types[2], + role=roles[2], + site=sites[2], + location=locations[2], + rack=racks[2], + status='offline', + ), + # For cable connections + Device( + name=None, + device_type=device_types[2], + role=roles[2], + site=sites[3], + status='offline' + ), ) Device.objects.bulk_create(devices) @@ -3428,9 +3676,33 @@ class PowerOutletTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedF PowerPort.objects.bulk_create(power_ports) power_outlets = ( - PowerOutlet(device=devices[0], module=modules[0], name='Power Outlet 1', label='A', feed_leg=PowerOutletFeedLegChoices.FEED_LEG_A, description='First', color='ff0000'), - PowerOutlet(device=devices[1], module=modules[1], name='Power Outlet 2', label='B', feed_leg=PowerOutletFeedLegChoices.FEED_LEG_B, description='Second', color='00ff00'), - PowerOutlet(device=devices[2], module=modules[2], name='Power Outlet 3', label='C', feed_leg=PowerOutletFeedLegChoices.FEED_LEG_C, description='Third', color='0000ff'), + PowerOutlet( + device=devices[0], + module=modules[0], + name='Power Outlet 1', + label='A', + feed_leg=PowerOutletFeedLegChoices.FEED_LEG_A, + description='First', + color='ff0000', + ), + PowerOutlet( + device=devices[1], + module=modules[1], + name='Power Outlet 2', + label='B', + feed_leg=PowerOutletFeedLegChoices.FEED_LEG_B, + description='Second', + color='00ff00', + ), + PowerOutlet( + device=devices[2], + module=modules[2], + name='Power Outlet 3', + label='C', + feed_leg=PowerOutletFeedLegChoices.FEED_LEG_C, + description='Third', + color='0000ff', + ), ) PowerOutlet.objects.bulk_create(power_outlets) @@ -3672,8 +3944,12 @@ class InterfaceTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil # Virtual Device Context Creation vdcs = ( - VirtualDeviceContext(device=devices[4], name='VDC 1', identifier=1, status=VirtualDeviceContextStatusChoices.STATUS_ACTIVE), - VirtualDeviceContext(device=devices[4], name='VDC 2', identifier=2, status=VirtualDeviceContextStatusChoices.STATUS_PLANNED), + VirtualDeviceContext( + device=devices[4], name='VDC 1', identifier=1, status=VirtualDeviceContextStatusChoices.STATUS_ACTIVE + ), + VirtualDeviceContext( + device=devices[4], name='VDC 2', identifier=2, status=VirtualDeviceContextStatusChoices.STATUS_PLANNED + ), ) VirtualDeviceContext.objects.bulk_create(vdcs) @@ -3886,9 +4162,24 @@ class InterfaceTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil # Create child interfaces parent_interface = Interface.objects.first() child_interfaces = ( - Interface(device=parent_interface.device, name='Child 1', parent=parent_interface, type=InterfaceTypeChoices.TYPE_VIRTUAL), - Interface(device=parent_interface.device, name='Child 2', parent=parent_interface, type=InterfaceTypeChoices.TYPE_VIRTUAL), - Interface(device=parent_interface.device, name='Child 3', parent=parent_interface, type=InterfaceTypeChoices.TYPE_VIRTUAL), + Interface( + device=parent_interface.device, + name='Child 1', + parent=parent_interface, + type=InterfaceTypeChoices.TYPE_VIRTUAL, + ), + Interface( + device=parent_interface.device, + name='Child 2', + parent=parent_interface, + type=InterfaceTypeChoices.TYPE_VIRTUAL, + ), + Interface( + device=parent_interface.device, + name='Child 3', + parent=parent_interface, + type=InterfaceTypeChoices.TYPE_VIRTUAL, + ), ) Interface.objects.bulk_create(child_interfaces) @@ -3899,9 +4190,24 @@ class InterfaceTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil # Create bridged interfaces bridge_interface = Interface.objects.first() bridged_interfaces = ( - Interface(device=bridge_interface.device, name='Bridged 1', bridge=bridge_interface, type=InterfaceTypeChoices.TYPE_1GE_FIXED), - Interface(device=bridge_interface.device, name='Bridged 2', bridge=bridge_interface, type=InterfaceTypeChoices.TYPE_1GE_FIXED), - Interface(device=bridge_interface.device, name='Bridged 3', bridge=bridge_interface, type=InterfaceTypeChoices.TYPE_1GE_FIXED), + Interface( + device=bridge_interface.device, + name='Bridged 1', + bridge=bridge_interface, + type=InterfaceTypeChoices.TYPE_1GE_FIXED, + ), + Interface( + device=bridge_interface.device, + name='Bridged 2', + bridge=bridge_interface, + type=InterfaceTypeChoices.TYPE_1GE_FIXED, + ), + Interface( + device=bridge_interface.device, + name='Bridged 3', + bridge=bridge_interface, + type=InterfaceTypeChoices.TYPE_1GE_FIXED, + ), ) Interface.objects.bulk_create(bridged_interfaces) @@ -4134,10 +4440,41 @@ class FrontPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil Rack.objects.bulk_create(racks) devices = ( - Device(name='Device 1', device_type=device_types[0], role=roles[0], site=sites[0], location=locations[0], rack=racks[0], status='active'), - Device(name='Device 2', device_type=device_types[1], role=roles[1], site=sites[1], location=locations[1], rack=racks[1], status='planned'), - Device(name='Device 3', device_type=device_types[2], role=roles[2], site=sites[2], location=locations[2], rack=racks[2], status='offline'), - Device(name=None, device_type=device_types[2], role=roles[2], site=sites[3], status='offline'), # For cable connections + Device( + name='Device 1', + device_type=device_types[0], + role=roles[0], + site=sites[0], + location=locations[0], + rack=racks[0], + status='active', + ), + Device( + name='Device 2', + device_type=device_types[1], + role=roles[1], + site=sites[1], + location=locations[1], + rack=racks[1], + status='planned', + ), + Device( + name='Device 3', + device_type=device_types[2], + role=roles[2], + site=sites[2], + location=locations[2], + rack=racks[2], + status='offline', + ), + # For cable connections + Device( + name=None, + device_type=device_types[2], + role=roles[2], + site=sites[3], + status='offline' + ), ) Device.objects.bulk_create(devices) @@ -4167,12 +4504,63 @@ class FrontPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil RearPort.objects.bulk_create(rear_ports) front_ports = ( - FrontPort(device=devices[0], module=modules[0], name='Front Port 1', label='A', type=PortTypeChoices.TYPE_8P8C, color=ColorChoices.COLOR_RED, rear_port=rear_ports[0], rear_port_position=1, description='First'), - FrontPort(device=devices[1], module=modules[1], name='Front Port 2', label='B', type=PortTypeChoices.TYPE_110_PUNCH, color=ColorChoices.COLOR_GREEN, rear_port=rear_ports[1], rear_port_position=2, description='Second'), - FrontPort(device=devices[2], module=modules[2], name='Front Port 3', label='C', type=PortTypeChoices.TYPE_BNC, color=ColorChoices.COLOR_BLUE, rear_port=rear_ports[2], rear_port_position=3, description='Third'), - FrontPort(device=devices[3], name='Front Port 4', label='D', type=PortTypeChoices.TYPE_FC, rear_port=rear_ports[3], rear_port_position=1), - FrontPort(device=devices[3], name='Front Port 5', label='E', type=PortTypeChoices.TYPE_FC, rear_port=rear_ports[4], rear_port_position=1), - FrontPort(device=devices[3], name='Front Port 6', label='F', type=PortTypeChoices.TYPE_FC, rear_port=rear_ports[5], rear_port_position=1), + FrontPort( + device=devices[0], + module=modules[0], + name='Front Port 1', + label='A', + type=PortTypeChoices.TYPE_8P8C, + color=ColorChoices.COLOR_RED, + rear_port=rear_ports[0], + rear_port_position=1, + description='First', + ), + FrontPort( + device=devices[1], + module=modules[1], + name='Front Port 2', + label='B', + type=PortTypeChoices.TYPE_110_PUNCH, + color=ColorChoices.COLOR_GREEN, + rear_port=rear_ports[1], + rear_port_position=2, + description='Second', + ), + FrontPort( + device=devices[2], + module=modules[2], + name='Front Port 3', + label='C', + type=PortTypeChoices.TYPE_BNC, + color=ColorChoices.COLOR_BLUE, + rear_port=rear_ports[2], + rear_port_position=3, + description='Third', + ), + FrontPort( + device=devices[3], + name='Front Port 4', + label='D', + type=PortTypeChoices.TYPE_FC, + rear_port=rear_ports[3], + rear_port_position=1, + ), + FrontPort( + device=devices[3], + name='Front Port 5', + label='E', + type=PortTypeChoices.TYPE_FC, + rear_port=rear_ports[4], + rear_port_position=1, + ), + FrontPort( + device=devices[3], + name='Front Port 6', + label='F', + type=PortTypeChoices.TYPE_FC, + rear_port=rear_ports[5], + rear_port_position=1, + ), ) FrontPort.objects.bulk_create(front_ports) @@ -4324,10 +4712,41 @@ class RearPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilt Rack.objects.bulk_create(racks) devices = ( - Device(name='Device 1', device_type=device_types[0], role=roles[0], site=sites[0], location=locations[0], rack=racks[0], status='active'), - Device(name='Device 2', device_type=device_types[1], role=roles[1], site=sites[1], location=locations[1], rack=racks[1], status='planned'), - Device(name='Device 3', device_type=device_types[2], role=roles[2], site=sites[2], location=locations[2], rack=racks[2], status='offline'), - Device(name=None, device_type=device_types[2], role=roles[2], site=sites[3], status='offline'), # For cable connections + Device( + name='Device 1', + device_type=device_types[0], + role=roles[0], + site=sites[0], + location=locations[0], + rack=racks[0], + status='active', + ), + Device( + name='Device 2', + device_type=device_types[1], + role=roles[1], + site=sites[1], + location=locations[1], + rack=racks[1], + status='planned', + ), + Device( + name='Device 3', + device_type=device_types[2], + role=roles[2], + site=sites[2], + location=locations[2], + rack=racks[2], + status='offline', + ), + # For cable connections + Device( + name=None, + device_type=device_types[2], + role=roles[2], + site=sites[3], + status='offline' + ), ) Device.objects.bulk_create(devices) @@ -4347,9 +4766,36 @@ class RearPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilt Module.objects.bulk_create(modules) rear_ports = ( - RearPort(device=devices[0], module=modules[0], name='Rear Port 1', label='A', type=PortTypeChoices.TYPE_8P8C, color=ColorChoices.COLOR_RED, positions=1, description='First'), - RearPort(device=devices[1], module=modules[1], name='Rear Port 2', label='B', type=PortTypeChoices.TYPE_110_PUNCH, color=ColorChoices.COLOR_GREEN, positions=2, description='Second'), - RearPort(device=devices[2], module=modules[2], name='Rear Port 3', label='C', type=PortTypeChoices.TYPE_BNC, color=ColorChoices.COLOR_BLUE, positions=3, description='Third'), + RearPort( + device=devices[0], + module=modules[0], + name='Rear Port 1', + label='A', + type=PortTypeChoices.TYPE_8P8C, + color=ColorChoices.COLOR_RED, + positions=1, + description='First', + ), + RearPort( + device=devices[1], + module=modules[1], + name='Rear Port 2', + label='B', + type=PortTypeChoices.TYPE_110_PUNCH, + color=ColorChoices.COLOR_GREEN, + positions=2, + description='Second', + ), + RearPort( + device=devices[2], + module=modules[2], + name='Rear Port 3', + label='C', + type=PortTypeChoices.TYPE_BNC, + color=ColorChoices.COLOR_BLUE, + positions=3, + description='Third', + ), RearPort(device=devices[3], name='Rear Port 4', label='D', type=PortTypeChoices.TYPE_FC, positions=4), RearPort(device=devices[3], name='Rear Port 5', label='E', type=PortTypeChoices.TYPE_FC, positions=5), RearPort(device=devices[3], name='Rear Port 6', label='F', type=PortTypeChoices.TYPE_FC, positions=6), @@ -4506,9 +4952,33 @@ class ModuleBayTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil Rack.objects.bulk_create(racks) devices = ( - Device(name='Device 1', device_type=device_types[0], role=roles[0], site=sites[0], location=locations[0], rack=racks[0], status='active'), - Device(name='Device 2', device_type=device_types[1], role=roles[1], site=sites[1], location=locations[1], rack=racks[1], status='planned'), - Device(name='Device 3', device_type=device_types[2], role=roles[2], site=sites[2], location=locations[2], rack=racks[2], status='offline'), + Device( + name='Device 1', + device_type=device_types[0], + role=roles[0], + site=sites[0], + location=locations[0], + rack=racks[0], + status='active', + ), + Device( + name='Device 2', + device_type=device_types[1], + role=roles[1], + site=sites[1], + location=locations[1], + rack=racks[1], + status='planned', + ), + Device( + name='Device 3', + device_type=device_types[2], + role=roles[2], + site=sites[2], + location=locations[2], + rack=racks[2], + status='offline', + ), ) Device.objects.bulk_create(devices) @@ -4654,9 +5124,33 @@ class DeviceBayTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil Rack.objects.bulk_create(racks) devices = ( - Device(name='Device 1', device_type=device_types[0], role=roles[0], site=sites[0], location=locations[0], rack=racks[0], status='active'), - Device(name='Device 2', device_type=device_types[1], role=roles[1], site=sites[1], location=locations[1], rack=racks[1], status='planned'), - Device(name='Device 3', device_type=device_types[2], role=roles[2], site=sites[2], location=locations[2], rack=racks[2], status='offline'), + Device( + name='Device 1', + device_type=device_types[0], + role=roles[0], + site=sites[0], + location=locations[0], + rack=racks[0], + status='active', + ), + Device( + name='Device 2', + device_type=device_types[1], + role=roles[1], + site=sites[1], + location=locations[1], + rack=racks[1], + status='planned', + ), + Device( + name='Device 3', + device_type=device_types[2], + role=roles[2], + site=sites[2], + location=locations[2], + rack=racks[2], + status='offline', + ), ) Device.objects.bulk_create(devices) @@ -4788,9 +5282,30 @@ class InventoryItemTestCase(TestCase, ChangeLoggedFilterSetTests): Rack.objects.bulk_create(racks) devices = ( - Device(name='Device 1', device_type=device_types[0], role=roles[0], site=sites[0], location=locations[0], rack=racks[0]), - Device(name='Device 2', device_type=device_types[1], role=roles[1], site=sites[1], location=locations[1], rack=racks[1]), - Device(name='Device 3', device_type=device_types[2], role=roles[2], site=sites[2], location=locations[2], rack=racks[2]), + Device( + name='Device 1', + device_type=device_types[0], + role=roles[0], + site=sites[0], + location=locations[0], + rack=racks[0], + ), + Device( + name='Device 2', + device_type=device_types[1], + role=roles[1], + site=sites[1], + location=locations[1], + rack=racks[1], + ), + Device( + name='Device 3', + device_type=device_types[2], + role=roles[2], + site=sites[2], + location=locations[2], + rack=racks[2], + ), ) Device.objects.bulk_create(devices) @@ -4808,9 +5323,48 @@ class InventoryItemTestCase(TestCase, ChangeLoggedFilterSetTests): ) inventory_items = ( - InventoryItem(device=devices[0], role=roles[0], manufacturer=manufacturers[0], name='Inventory Item 1', label='A', part_id='1001', serial='ABC', asset_tag='1001', discovered=True, status=ModuleStatusChoices.STATUS_ACTIVE, description='First', component=components[0]), - InventoryItem(device=devices[1], role=roles[1], manufacturer=manufacturers[1], name='Inventory Item 2', label='B', part_id='1002', serial='DEF', asset_tag='1002', discovered=True, status=ModuleStatusChoices.STATUS_PLANNED, description='Second', component=components[1]), - InventoryItem(device=devices[2], role=roles[2], manufacturer=manufacturers[2], name='Inventory Item 3', label='C', part_id='1003', serial='GHI', asset_tag='1003', discovered=False, status=ModuleStatusChoices.STATUS_FAILED, description='Third', component=components[2]), + InventoryItem( + device=devices[0], + role=roles[0], + manufacturer=manufacturers[0], + name='Inventory Item 1', + label='A', + part_id='1001', + serial='ABC', + asset_tag='1001', + discovered=True, + status=ModuleStatusChoices.STATUS_ACTIVE, + description='First', + component=components[0], + ), + InventoryItem( + device=devices[1], + role=roles[1], + manufacturer=manufacturers[1], + name='Inventory Item 2', + label='B', + part_id='1002', + serial='DEF', + asset_tag='1002', + discovered=True, + status=ModuleStatusChoices.STATUS_PLANNED, + description='Second', + component=components[1], + ), + InventoryItem( + device=devices[2], + role=roles[2], + manufacturer=manufacturers[2], + name='Inventory Item 3', + label='C', + part_id='1003', + serial='GHI', + asset_tag='1003', + discovered=False, + status=ModuleStatusChoices.STATUS_FAILED, + description='Third', + component=components[2], + ), ) for i in inventory_items: i.save() @@ -5127,12 +5681,60 @@ class CableTestCase(TestCase, ChangeLoggedFilterSetTests): role = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1') devices = ( - Device(name='Device 1', device_type=device_type, role=role, site=sites[0], rack=racks[0], location=locations[0], position=1), - Device(name='Device 2', device_type=device_type, role=role, site=sites[0], rack=racks[0], location=locations[0], position=2), - Device(name='Device 3', device_type=device_type, role=role, site=sites[1], rack=racks[1], location=locations[1], position=1), - Device(name='Device 4', device_type=device_type, role=role, site=sites[1], rack=racks[1], location=locations[1], position=2), - Device(name='Device 5', device_type=device_type, role=role, site=sites[2], rack=racks[2], location=locations[2], position=1), - Device(name='Device 6', device_type=device_type, role=role, site=sites[2], rack=racks[2], location=locations[2], position=2), + Device( + name='Device 1', + device_type=device_type, + role=role, + site=sites[0], + rack=racks[0], + location=locations[0], + position=1, + ), + Device( + name='Device 2', + device_type=device_type, + role=role, + site=sites[0], + rack=racks[0], + location=locations[0], + position=2, + ), + Device( + name='Device 3', + device_type=device_type, + role=role, + site=sites[1], + rack=racks[1], + location=locations[1], + position=1, + ), + Device( + name='Device 4', + device_type=device_type, + role=role, + site=sites[1], + rack=racks[1], + location=locations[1], + position=2, + ), + Device( + name='Device 5', + device_type=device_type, + role=role, + site=sites[2], + rack=racks[2], + location=locations[2], + position=1, + ), + Device( + name='Device 6', + device_type=device_type, + role=role, + site=sites[2], + rack=racks[2], + location=locations[2], + position=2, + ), ) Device.objects.bulk_create(devices) diff --git a/netbox/dcim/tests/test_models.py b/netbox/dcim/tests/test_models.py index 8d43d67ea..ff1eddd56 100644 --- a/netbox/dcim/tests/test_models.py +++ b/netbox/dcim/tests/test_models.py @@ -612,14 +612,31 @@ class DeviceTestCase(TestCase): device_role = DeviceRole.objects.first() # Device with site only should pass - Device(name='device1', site=sites[0], device_type=device_type, role=device_role).full_clean() + Device( + name='device1', + site=sites[0], + device_type=device_type, + role=device_role + ).full_clean() # Device with site, cluster non-site should pass - Device(name='device1', site=sites[0], device_type=device_type, role=device_role, cluster=clusters[2]).full_clean() + Device( + name='device1', + site=sites[0], + device_type=device_type, + role=device_role, + cluster=clusters[2] + ).full_clean() # Device with mismatched site & cluster should fail with self.assertRaises(ValidationError): - Device(name='device1', site=sites[0], device_type=device_type, role=device_role, cluster=clusters[1]).full_clean() + Device( + name='device1', + site=sites[0], + device_type=device_type, + role=device_role, + cluster=clusters[1] + ).full_clean() class ModuleBayTestCase(TestCase): @@ -636,7 +653,9 @@ class ModuleBayTestCase(TestCase): # Create a CustomField with a default value & assign it to all component models location = Location.objects.create(name='Location 1', slug='location-1', site=site) rack = Rack.objects.create(name='Rack 1', site=site) - device = Device.objects.create(name='Device 1', device_type=device_type, role=device_role, site=site, location=location, rack=rack) + device = Device.objects.create( + name='Device 1', device_type=device_type, role=device_role, site=site, location=location, rack=rack + ) module_bays = ( ModuleBay(device=device, name='Module Bay 1', label='A', description='First'), diff --git a/netbox/dcim/tests/test_views.py b/netbox/dcim/tests/test_views.py index 9850081d1..c2c5b6a01 100644 --- a/netbox/dcim/tests/test_views.py +++ b/netbox/dcim/tests/test_views.py @@ -196,9 +196,27 @@ class LocationTestCase(ViewTestCases.OrganizationalObjectViewTestCase): tenant = Tenant.objects.create(name='Tenant 1', slug='tenant-1') locations = ( - Location(name='Location 1', slug='location-1', site=site, status=LocationStatusChoices.STATUS_ACTIVE, tenant=tenant), - Location(name='Location 2', slug='location-2', site=site, status=LocationStatusChoices.STATUS_ACTIVE, tenant=tenant), - Location(name='Location 3', slug='location-3', site=site, status=LocationStatusChoices.STATUS_ACTIVE, tenant=tenant), + Location( + name='Location 1', + slug='location-1', + site=site, + status=LocationStatusChoices.STATUS_ACTIVE, + tenant=tenant, + ), + Location( + name='Location 2', + slug='location-2', + site=site, + status=LocationStatusChoices.STATUS_ACTIVE, + tenant=tenant, + ), + Location( + name='Location 3', + slug='location-3', + site=site, + status=LocationStatusChoices.STATUS_ACTIVE, + tenant=tenant, + ), ) for location in locations: location.save() @@ -346,9 +364,24 @@ class RackTypeTestCase(ViewTestCases.PrimaryObjectViewTestCase): Manufacturer.objects.bulk_create(manufacturers) rack_types = ( - RackType(manufacturer=manufacturers[0], model='RackType 1', slug='rack-type-1', form_factor=RackFormFactorChoices.TYPE_CABINET,), - RackType(manufacturer=manufacturers[0], model='RackType 2', slug='rack-type-2', form_factor=RackFormFactorChoices.TYPE_CABINET,), - RackType(manufacturer=manufacturers[0], model='RackType 3', slug='rack-type-3', form_factor=RackFormFactorChoices.TYPE_CABINET,), + RackType( + manufacturer=manufacturers[0], + model='RackType 1', + slug='rack-type-1', + form_factor=RackFormFactorChoices.TYPE_CABINET, + ), + RackType( + manufacturer=manufacturers[0], + model='RackType 2', + slug='rack-type-2', + form_factor=RackFormFactorChoices.TYPE_CABINET, + ), + RackType( + manufacturer=manufacturers[0], + model='RackType 3', + slug='rack-type-3', + form_factor=RackFormFactorChoices.TYPE_CABINET, + ), ) RackType.objects.bulk_create(rack_types) @@ -692,9 +725,15 @@ class DeviceTypeTestCase( ) RearPortTemplate.objects.bulk_create(rear_ports) front_ports = ( - FrontPortTemplate(device_type=devicetype, name='Front Port 1', rear_port=rear_ports[0], rear_port_position=1), - FrontPortTemplate(device_type=devicetype, name='Front Port 2', rear_port=rear_ports[1], rear_port_position=1), - FrontPortTemplate(device_type=devicetype, name='Front Port 3', rear_port=rear_ports[2], rear_port_position=1), + FrontPortTemplate( + device_type=devicetype, name='Front Port 1', rear_port=rear_ports[0], rear_port_position=1 + ), + FrontPortTemplate( + device_type=devicetype, name='Front Port 2', rear_port=rear_ports[1], rear_port_position=1 + ), + FrontPortTemplate( + device_type=devicetype, name='Front Port 3', rear_port=rear_ports[2], rear_port_position=1 + ), ) FrontPortTemplate.objects.bulk_create(front_ports) @@ -1081,9 +1120,15 @@ class ModuleTypeTestCase( ) RearPortTemplate.objects.bulk_create(rear_ports) front_ports = ( - FrontPortTemplate(module_type=moduletype, name='Front Port 1', rear_port=rear_ports[0], rear_port_position=1), - FrontPortTemplate(module_type=moduletype, name='Front Port 2', rear_port=rear_ports[1], rear_port_position=1), - FrontPortTemplate(module_type=moduletype, name='Front Port 3', rear_port=rear_ports[2], rear_port_position=1), + FrontPortTemplate( + module_type=moduletype, name='Front Port 1', rear_port=rear_ports[0], rear_port_position=1 + ), + FrontPortTemplate( + module_type=moduletype, name='Front Port 2', rear_port=rear_ports[1], rear_port_position=1 + ), + FrontPortTemplate( + module_type=moduletype, name='Front Port 3', rear_port=rear_ports[2], rear_port_position=1 + ), ) FrontPortTemplate.objects.bulk_create(front_ports) @@ -1453,11 +1498,19 @@ class FrontPortTemplateTestCase(ViewTestCases.DeviceComponentTemplateViewTestCas ) RearPortTemplate.objects.bulk_create(rearports) - FrontPortTemplate.objects.bulk_create(( - FrontPortTemplate(device_type=devicetype, name='Front Port Template 1', rear_port=rearports[0], rear_port_position=1), - FrontPortTemplate(device_type=devicetype, name='Front Port Template 2', rear_port=rearports[1], rear_port_position=1), - FrontPortTemplate(device_type=devicetype, name='Front Port Template 3', rear_port=rearports[2], rear_port_position=1), - )) + FrontPortTemplate.objects.bulk_create( + ( + FrontPortTemplate( + device_type=devicetype, name='Front Port Template 1', rear_port=rearports[0], rear_port_position=1 + ), + FrontPortTemplate( + device_type=devicetype, name='Front Port Template 2', rear_port=rearports[1], rear_port_position=1 + ), + FrontPortTemplate( + device_type=devicetype, name='Front Port Template 3', rear_port=rearports[2], rear_port_position=1 + ), + ) + ) cls.form_data = { 'device_type': devicetype.pk, @@ -1550,7 +1603,12 @@ class DeviceBayTemplateTestCase(ViewTestCases.DeviceComponentTemplateViewTestCas @classmethod def setUpTestData(cls): manufacturer = Manufacturer.objects.create(name='Manufacturer 1', slug='manufacturer-1') - devicetype = DeviceType.objects.create(manufacturer=manufacturer, model='Device Type 1', slug='device-type-1', subdevice_role=SubdeviceRoleChoices.ROLE_PARENT) + devicetype = DeviceType.objects.create( + manufacturer=manufacturer, + model='Device Type 1', + slug='device-type-1', + subdevice_role=SubdeviceRoleChoices.ROLE_PARENT + ) DeviceBayTemplate.objects.bulk_create(( DeviceBayTemplate(device_type=devicetype, name='Device Bay Template 1'), @@ -1584,12 +1642,20 @@ class InventoryItemTemplateTestCase(ViewTestCases.DeviceComponentTemplateViewTes Manufacturer(name='Manufacturer 2', slug='manufacturer-2'), ) Manufacturer.objects.bulk_create(manufacturers) - devicetype = DeviceType.objects.create(manufacturer=manufacturers[0], model='Device Type 1', slug='device-type-1') + devicetype = DeviceType.objects.create( + manufacturer=manufacturers[0], model='Device Type 1', slug='device-type-1' + ) inventory_item_templates = ( - InventoryItemTemplate(device_type=devicetype, name='Inventory Item Template 1', manufacturer=manufacturers[0]), - InventoryItemTemplate(device_type=devicetype, name='Inventory Item Template 2', manufacturer=manufacturers[0]), - InventoryItemTemplate(device_type=devicetype, name='Inventory Item Template 3', manufacturer=manufacturers[0]), + InventoryItemTemplate( + device_type=devicetype, name='Inventory Item Template 1', manufacturer=manufacturers[0] + ), + InventoryItemTemplate( + device_type=devicetype, name='Inventory Item Template 2', manufacturer=manufacturers[0] + ), + InventoryItemTemplate( + device_type=devicetype, name='Inventory Item Template 3', manufacturer=manufacturers[0] + ), ) for item in inventory_item_templates: item.save() @@ -1741,9 +1807,30 @@ class DeviceTestCase(ViewTestCases.PrimaryObjectViewTestCase): Platform.objects.bulk_create(platforms) devices = ( - Device(name='Device 1', site=sites[0], rack=racks[0], device_type=devicetypes[0], role=roles[0], platform=platforms[0]), - Device(name='Device 2', site=sites[0], rack=racks[0], device_type=devicetypes[0], role=roles[0], platform=platforms[0]), - Device(name='Device 3', site=sites[0], rack=racks[0], device_type=devicetypes[0], role=roles[0], platform=platforms[0]), + Device( + name='Device 1', + site=sites[0], + rack=racks[0], + device_type=devicetypes[0], + role=roles[0], + platform=platforms[0], + ), + Device( + name='Device 2', + site=sites[0], + rack=racks[0], + device_type=devicetypes[0], + role=roles[0], + platform=platforms[0], + ), + Device( + name='Device 3', + site=sites[0], + rack=racks[0], + device_type=devicetypes[0], + role=roles[0], + platform=platforms[0], + ), ) Device.objects.bulk_create(devices) @@ -1778,10 +1865,22 @@ class DeviceTestCase(ViewTestCases.PrimaryObjectViewTestCase): } cls.csv_data = ( - "role,manufacturer,device_type,status,name,site,location,rack,position,face,virtual_chassis,vc_position,vc_priority", - "Device Role 1,Manufacturer 1,Device Type 1,active,Device 4,Site 1,Location 1,Rack 1,10,front,Virtual Chassis 1,1,10", - "Device Role 1,Manufacturer 1,Device Type 1,active,Device 5,Site 1,Location 1,Rack 1,20,front,Virtual Chassis 1,2,20", - "Device Role 1,Manufacturer 1,Device Type 1,active,Device 6,Site 1,Location 1,Rack 1,30,front,Virtual Chassis 1,3,30", + ( + "role,manufacturer,device_type,status,name,site,location,rack,position,face,virtual_chassis," + "vc_position,vc_priority" + ), + ( + "Device Role 1,Manufacturer 1,Device Type 1,active,Device 4,Site 1,Location 1,Rack 1,10,front," + "Virtual Chassis 1,1,10" + ), + ( + "Device Role 1,Manufacturer 1,Device Type 1,active,Device 5,Site 1,Location 1,Rack 1,20,front," + "Virtual Chassis 1,2,20" + ), + ( + "Device Role 1,Manufacturer 1,Device Type 1,active,Device 6,Site 1,Location 1,Rack 1,30,front," + "Virtual Chassis 1,3,30" + ), ) cls.csv_update_data = ( @@ -2884,9 +2983,15 @@ class InventoryItemTestCase(ViewTestCases.DeviceComponentViewTestCase): ) InventoryItemRole.objects.bulk_create(roles) - inventory_item1 = InventoryItem.objects.create(device=device, name='Inventory Item 1', role=roles[0], manufacturer=manufacturer) - inventory_item2 = InventoryItem.objects.create(device=device, name='Inventory Item 2', role=roles[0], manufacturer=manufacturer) - inventory_item3 = InventoryItem.objects.create(device=device, name='Inventory Item 3', role=roles[0], manufacturer=manufacturer) + inventory_item1 = InventoryItem.objects.create( + device=device, name='Inventory Item 1', role=roles[0], manufacturer=manufacturer + ) + inventory_item2 = InventoryItem.objects.create( + device=device, name='Inventory Item 2', role=roles[0], manufacturer=manufacturer + ) + inventory_item3 = InventoryItem.objects.create( + device=device, name='Inventory Item 3', role=roles[0], manufacturer=manufacturer + ) tags = create_tags('Alpha', 'Bravo', 'Charlie') diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index f6e7b90be..731034dc1 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -244,7 +244,9 @@ class RegionView(GetRelatedModelsMixin, generic.ObjectView): (Location.objects.restrict(request.user, 'view').filter(site__region__in=regions), 'region_id'), (Rack.objects.restrict(request.user, 'view').filter(site__region__in=regions), 'region_id'), ( - Circuit.objects.restrict(request.user, 'view').filter(terminations___region=instance).distinct(), + Circuit.objects.restrict(request.user, 'view').filter( + terminations___region=instance + ).distinct(), 'region_id' ), ), @@ -335,7 +337,9 @@ class SiteGroupView(GetRelatedModelsMixin, generic.ObjectView): (Location.objects.restrict(request.user, 'view').filter(site__group__in=groups), 'site_group_id'), (Rack.objects.restrict(request.user, 'view').filter(site__group__in=groups), 'site_group_id'), ( - Circuit.objects.restrict(request.user, 'view').filter(terminations___site_group=instance).distinct(), + Circuit.objects.restrict(request.user, 'view').filter( + terminations___site_group=instance + ).distinct(), 'site_group_id' ), ), @@ -507,7 +511,9 @@ class LocationView(GetRelatedModelsMixin, generic.ObjectView): [CableTermination], ( ( - Circuit.objects.restrict(request.user, 'view').filter(terminations___location=instance).distinct(), + Circuit.objects.restrict(request.user, 'view').filter( + terminations___location=instance + ).distinct(), 'location_id' ), ), @@ -3729,7 +3735,9 @@ class VirtualChassisAddMemberView(ObjectPermissionRequiredMixin, GetReturnURLMix membership_form.save() messages.success(request, mark_safe( - _('Added member {device}').format(url=device.get_absolute_url(), device=escape(device)) + _('Added member {device}').format( + url=device.get_absolute_url(), device=escape(device) + ) )) if '_addanother' in request.POST: diff --git a/netbox/extras/management/commands/reindex.py b/netbox/extras/management/commands/reindex.py index 21442be93..5495bbf5f 100644 --- a/netbox/extras/management/commands/reindex.py +++ b/netbox/extras/management/commands/reindex.py @@ -53,7 +53,8 @@ class Command(BaseCommand): else: raise CommandError( - f"Invalid model: {label}. Model names must be in the format or .." + f"Invalid model: {label}. Model names must be in the format or " + f".." ) return indexers diff --git a/netbox/extras/migrations/0001_squashed.py b/netbox/extras/migrations/0001_squashed.py index 6f1f77e53..a2514fa5e 100644 --- a/netbox/extras/migrations/0001_squashed.py +++ b/netbox/extras/migrations/0001_squashed.py @@ -9,7 +9,6 @@ import utilities.validators class Migration(migrations.Migration): - initial = True dependencies = [ @@ -99,8 +98,22 @@ class Migration(migrations.Migration): 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')), + ( + '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( @@ -116,9 +129,32 @@ class Migration(migrations.Migration): ('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)), + ( + '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'], @@ -133,8 +169,16 @@ class Migration(migrations.Migration): ('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)), + ( + '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', @@ -151,8 +195,24 @@ class Migration(migrations.Migration): ('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)), + ( + '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'], @@ -163,12 +223,20 @@ class Migration(migrations.Migration): 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', + 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')), + ( + 'content_type', + models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype'), + ), ], options={ 'ordering': ('name', 'pk'), @@ -184,7 +252,10 @@ class Migration(migrations.Migration): ('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')), + ( + 'content_type', + models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype'), + ), ], options={ 'ordering': ['content_type', 'name'], @@ -201,7 +272,10 @@ class Migration(migrations.Migration): ('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')), + ( + 'content_type', + models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype'), + ), ], options={ 'ordering': ['group_name', 'weight', 'name'], @@ -221,8 +295,16 @@ class Migration(migrations.Migration): ('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)), + ( + '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={ diff --git a/netbox/extras/migrations/0002_squashed_0059.py b/netbox/extras/migrations/0002_squashed_0059.py index a403a0e19..b664b286e 100644 --- a/netbox/extras/migrations/0002_squashed_0059.py +++ b/netbox/extras/migrations/0002_squashed_0059.py @@ -2,7 +2,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('dcim', '0002_auto_20160622_1821'), ('extras', '0001_initial'), diff --git a/netbox/extras/migrations/0060_squashed_0086.py b/netbox/extras/migrations/0060_squashed_0086.py index 0d5d03008..3bde7480f 100644 --- a/netbox/extras/migrations/0060_squashed_0086.py +++ b/netbox/extras/migrations/0060_squashed_0086.py @@ -12,7 +12,6 @@ import utilities.json class Migration(migrations.Migration): - replaces = [ ('extras', '0060_customlink_button_class'), ('extras', '0061_extras_change_logging'), @@ -40,7 +39,7 @@ class Migration(migrations.Migration): ('extras', '0083_search'), ('extras', '0084_staging'), ('extras', '0085_synced_data'), - ('extras', '0086_configtemplate') + ('extras', '0086_configtemplate'), ] dependencies = [ @@ -114,7 +113,23 @@ class Migration(migrations.Migration): 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='__')]), + 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='__', + ), + ], + ), ), migrations.AlterField( model_name='customfield', @@ -134,7 +149,9 @@ class Migration(migrations.Migration): 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'), + field=models.ForeignKey( + blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='contenttypes.contenttype' + ), ), migrations.AddField( model_name='customlink', @@ -314,11 +331,16 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='exporttemplate', - constraint=models.UniqueConstraint(fields=('content_type', 'name'), name='extras_exporttemplate_unique_content_type_name'), + 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'), + constraint=models.UniqueConstraint( + fields=('payload_url', 'type_create', 'type_update', 'type_delete'), + name='extras_webhook_unique_payload_url_types', + ), ), migrations.AddField( model_name='jobresult', @@ -328,7 +350,9 @@ class Migration(migrations.Migration): migrations.AddField( model_name='jobresult', name='interval', - field=models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)]), + field=models.PositiveIntegerField( + blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)] + ), ), migrations.AddField( model_name='jobresult', @@ -379,7 +403,12 @@ class Migration(migrations.Migration): ('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)), + ( + 'user', + models.ForeignKey( + blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL + ), + ), ], options={ 'ordering': ('weight', 'name'), @@ -400,7 +429,12 @@ class Migration(migrations.Migration): ('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')), + ( + 'object_type', + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, related_name='+', to='contenttypes.contenttype' + ), + ), ], options={ 'ordering': ('weight', 'object_type', 'object_id'), @@ -414,7 +448,12 @@ class Migration(migrations.Migration): ('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)), + ( + 'user', + models.ForeignKey( + blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL + ), + ), ], options={ 'ordering': ('name',), @@ -429,8 +468,18 @@ class Migration(migrations.Migration): ('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')), + ( + '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',), @@ -439,7 +488,13 @@ class Migration(migrations.Migration): 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'), + 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', @@ -449,7 +504,13 @@ class Migration(migrations.Migration): 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'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='+', + to='core.datasource', + ), ), migrations.AddField( model_name='configcontext', @@ -464,7 +525,13 @@ class Migration(migrations.Migration): 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'), + 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', @@ -474,7 +541,13 @@ class Migration(migrations.Migration): 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'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='+', + to='core.datasource', + ), ), migrations.AddField( model_name='exporttemplate', @@ -498,8 +571,26 @@ class Migration(migrations.Migration): ('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')), + ( + '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')), ], diff --git a/netbox/extras/migrations/0087_squashed_0098.py b/netbox/extras/migrations/0087_squashed_0098.py index bbe7f79f5..839f4cbe4 100644 --- a/netbox/extras/migrations/0087_squashed_0098.py +++ b/netbox/extras/migrations/0087_squashed_0098.py @@ -9,7 +9,6 @@ import utilities.json class Migration(migrations.Migration): - replaces = [ ('extras', '0087_dashboard'), ('extras', '0088_jobresult_webhooks'), @@ -22,7 +21,7 @@ class Migration(migrations.Migration): ('extras', '0095_bookmarks'), ('extras', '0096_customfieldchoiceset'), ('extras', '0097_customfield_remove_choices'), - ('extras', '0098_webhook_custom_field_data_webhook_tags') + ('extras', '0098_webhook_custom_field_data_webhook_tags'), ] dependencies = [ @@ -39,7 +38,14 @@ class Migration(migrations.Migration): ('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)), + ( + 'user', + models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, + related_name='dashboard', + to=settings.AUTH_USER_MODEL, + ), + ), ], ), migrations.AddField( @@ -64,8 +70,7 @@ class Migration(migrations.Migration): ), migrations.CreateModel( name='ReportModule', - fields=[ - ], + fields=[], options={ 'proxy': True, 'ordering': ('file_root', 'file_path'), @@ -76,8 +81,7 @@ class Migration(migrations.Migration): ), migrations.CreateModel( name='ScriptModule', - fields=[ - ], + fields=[], options={ 'proxy': True, 'ordering': ('file_root', 'file_path'), @@ -108,7 +112,10 @@ class Migration(migrations.Migration): ('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')), + ( + '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={ @@ -117,7 +124,9 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='bookmark', - constraint=models.UniqueConstraint(fields=('object_type', 'object_id', 'user'), name='extras_bookmark_unique_per_object_and_user'), + constraint=models.UniqueConstraint( + fields=('object_type', 'object_id', 'user'), name='extras_bookmark_unique_per_object_and_user' + ), ), migrations.CreateModel( name='CustomFieldChoiceSet', @@ -128,7 +137,17 @@ class Migration(migrations.Migration): ('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)), + ( + '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={ @@ -138,7 +157,13 @@ class Migration(migrations.Migration): 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'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='choices_for', + to='extras.customfieldchoiceset', + ), ), migrations.RemoveField( model_name='customfield', diff --git a/netbox/extras/migrations/0099_cachedvalue_ordering.py b/netbox/extras/migrations/0099_cachedvalue_ordering.py index 242ffd983..36b91d59b 100644 --- a/netbox/extras/migrations/0099_cachedvalue_ordering.py +++ b/netbox/extras/migrations/0099_cachedvalue_ordering.py @@ -4,7 +4,6 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ ('extras', '0098_webhook_custom_field_data_webhook_tags'), ] diff --git a/netbox/extras/migrations/0100_customfield_ui_attrs.py b/netbox/extras/migrations/0100_customfield_ui_attrs.py index a4a713a86..b1a404d16 100644 --- a/netbox/extras/migrations/0100_customfield_ui_attrs.py +++ b/netbox/extras/migrations/0100_customfield_ui_attrs.py @@ -14,7 +14,6 @@ def update_ui_attrs(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('extras', '0099_cachedvalue_ordering'), ] @@ -30,10 +29,7 @@ class Migration(migrations.Migration): name='ui_visible', field=models.CharField(default='always', max_length=50), ), - migrations.RunPython( - code=update_ui_attrs, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=update_ui_attrs, reverse_code=migrations.RunPython.noop), migrations.RemoveField( model_name='customfield', name='ui_visibility', diff --git a/netbox/extras/migrations/0101_eventrule.py b/netbox/extras/migrations/0101_eventrule.py index 3d236c847..605307c27 100644 --- a/netbox/extras/migrations/0101_eventrule.py +++ b/netbox/extras/migrations/0101_eventrule.py @@ -8,8 +8,8 @@ from extras.choices import * def move_webhooks(apps, schema_editor): - Webhook = apps.get_model("extras", "Webhook") - EventRule = apps.get_model("extras", "EventRule") + Webhook = apps.get_model('extras', 'Webhook') + EventRule = apps.get_model('extras', 'EventRule') webhook_ct = ContentType.objects.get_for_model(Webhook).pk for webhook in Webhook.objects.all(): @@ -39,7 +39,6 @@ class Migration(migrations.Migration): ] operations = [ - # Create the EventRule model migrations.CreateModel( name='EventRule', @@ -93,12 +92,12 @@ class Migration(migrations.Migration): ), migrations.AddIndex( model_name='eventrule', - index=models.Index(fields=['action_object_type', 'action_object_id'], name='extras_even_action__d9e2af_idx'), + index=models.Index( + fields=['action_object_type', 'action_object_id'], name='extras_even_action__d9e2af_idx' + ), ), - # Replicate Webhook data migrations.RunPython(move_webhooks), - # Remove obsolete fields from Webhook migrations.RemoveConstraint( model_name='webhook', @@ -136,7 +135,6 @@ class Migration(migrations.Migration): model_name='webhook', name='type_update', ), - # Add description field to Webhook migrations.AddField( model_name='webhook', diff --git a/netbox/extras/migrations/0102_move_configrevision.py b/netbox/extras/migrations/0102_move_configrevision.py index 36eef1205..64ff8c9ad 100644 --- a/netbox/extras/migrations/0102_move_configrevision.py +++ b/netbox/extras/migrations/0102_move_configrevision.py @@ -13,7 +13,6 @@ def update_content_type(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('extras', '0101_eventrule'), ] @@ -32,8 +31,5 @@ class Migration(migrations.Migration): ), ], ), - migrations.RunPython( - code=update_content_type, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=update_content_type, reverse_code=migrations.RunPython.noop), ] diff --git a/netbox/extras/migrations/0103_gfk_indexes.py b/netbox/extras/migrations/0103_gfk_indexes.py index 2ccbdb2ff..f32b2e116 100644 --- a/netbox/extras/migrations/0103_gfk_indexes.py +++ b/netbox/extras/migrations/0103_gfk_indexes.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('extras', '0102_move_configrevision'), ] @@ -20,15 +19,21 @@ class Migration(migrations.Migration): ), migrations.AddIndex( model_name='journalentry', - index=models.Index(fields=['assigned_object_type', 'assigned_object_id'], name='extras_jour_assigne_76510f_idx'), + index=models.Index( + fields=['assigned_object_type', 'assigned_object_id'], name='extras_jour_assigne_76510f_idx' + ), ), migrations.AddIndex( model_name='objectchange', - index=models.Index(fields=['changed_object_type', 'changed_object_id'], name='extras_obje_changed_927fe5_idx'), + index=models.Index( + fields=['changed_object_type', 'changed_object_id'], name='extras_obje_changed_927fe5_idx' + ), ), migrations.AddIndex( model_name='objectchange', - index=models.Index(fields=['related_object_type', 'related_object_id'], name='extras_obje_related_bfcdef_idx'), + index=models.Index( + fields=['related_object_type', 'related_object_id'], name='extras_obje_related_bfcdef_idx' + ), ), migrations.AddIndex( model_name='stagedchange', diff --git a/netbox/extras/migrations/0105_customfield_min_max_values.py b/netbox/extras/migrations/0105_customfield_min_max_values.py index bcf3f97bd..71a0dcc68 100644 --- a/netbox/extras/migrations/0105_customfield_min_max_values.py +++ b/netbox/extras/migrations/0105_customfield_min_max_values.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('extras', '0104_stagedchange_remove_change_logging'), ] diff --git a/netbox/extras/migrations/0106_bookmark_user_cascade_deletion.py b/netbox/extras/migrations/0106_bookmark_user_cascade_deletion.py index d7bef2f0b..bc0e1bbd0 100644 --- a/netbox/extras/migrations/0106_bookmark_user_cascade_deletion.py +++ b/netbox/extras/migrations/0106_bookmark_user_cascade_deletion.py @@ -6,7 +6,6 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('extras', '0105_customfield_min_max_values'), diff --git a/netbox/extras/migrations/0107_cachedvalue_extras_cachedvalue_object.py b/netbox/extras/migrations/0107_cachedvalue_extras_cachedvalue_object.py index 15ce375a2..3f2907192 100644 --- a/netbox/extras/migrations/0107_cachedvalue_extras_cachedvalue_object.py +++ b/netbox/extras/migrations/0107_cachedvalue_extras_cachedvalue_object.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('extras', '0106_bookmark_user_cascade_deletion'), ] diff --git a/netbox/extras/migrations/0108_convert_reports_to_scripts.py b/netbox/extras/migrations/0108_convert_reports_to_scripts.py index b547c41c3..948bac754 100644 --- a/netbox/extras/migrations/0108_convert_reports_to_scripts.py +++ b/netbox/extras/migrations/0108_convert_reports_to_scripts.py @@ -12,16 +12,12 @@ def convert_reportmodule_jobs(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('extras', '0107_cachedvalue_extras_cachedvalue_object'), ] operations = [ - migrations.RunPython( - code=convert_reportmodule_jobs, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=convert_reportmodule_jobs, reverse_code=migrations.RunPython.noop), migrations.DeleteModel( name='Report', ), diff --git a/netbox/extras/migrations/0109_script_model.py b/netbox/extras/migrations/0109_script_model.py index 2fa0bf8aa..706a776af 100644 --- a/netbox/extras/migrations/0109_script_model.py +++ b/netbox/extras/migrations/0109_script_model.py @@ -55,9 +55,10 @@ def get_module_scripts(scriptmodule): """ Return a dictionary mapping of name and script class inside the passed ScriptModule. """ + def get_name(cls): # For child objects in submodules use the full import path w/o the root module as the name - return cls.full_name.split(".", maxsplit=1)[1] + return cls.full_name.split('.', maxsplit=1)[1] loader = SourceFileLoader(get_python_name(scriptmodule), get_full_path(scriptmodule)) try: @@ -100,17 +101,13 @@ def update_scripts(apps, schema_editor): ) # Update all Jobs associated with this ScriptModule & script name to point to the new Script object - Job.objects.filter( - object_type_id=scriptmodule_ct.id, - object_id=module.pk, - name=script_name - ).update(object_type_id=script_ct.id, object_id=script.pk) + Job.objects.filter(object_type_id=scriptmodule_ct.id, object_id=module.pk, name=script_name).update( + object_type_id=script_ct.id, object_id=script.pk + ) # Update all Jobs associated with this ScriptModule & script name to point to the new Script object - Job.objects.filter( - object_type_id=reportmodule_ct.id, - object_id=module.pk, - name=script_name - ).update(object_type_id=script_ct.id, object_id=script.pk) + Job.objects.filter(object_type_id=reportmodule_ct.id, object_id=module.pk, name=script_name).update( + object_type_id=script_ct.id, object_id=script.pk + ) def update_event_rules(apps, schema_editor): @@ -129,15 +126,12 @@ def update_event_rules(apps, schema_editor): for eventrule in EventRule.objects.filter(action_object_type=scriptmodule_ct): name = eventrule.action_parameters.get('script_name') obj, __ = Script.objects.get_or_create( - module_id=eventrule.action_object_id, - name=name, - defaults={'is_executable': False} + module_id=eventrule.action_object_id, name=name, defaults={'is_executable': False} ) EventRule.objects.filter(pk=eventrule.pk).update(action_object_type=script_ct, action_object_id=obj.id) class Migration(migrations.Migration): - dependencies = [ ('extras', '0108_convert_reports_to_scripts'), ] @@ -148,8 +142,16 @@ class Migration(migrations.Migration): fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), ('name', models.CharField(editable=False, max_length=79)), - ('module', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='scripts', to='extras.scriptmodule')), - ('is_executable', models.BooleanField(editable=False, default=True)) + ( + 'module', + models.ForeignKey( + editable=False, + on_delete=django.db.models.deletion.CASCADE, + related_name='scripts', + to='extras.scriptmodule', + ), + ), + ('is_executable', models.BooleanField(editable=False, default=True)), ], options={ 'ordering': ('module', 'name'), @@ -159,12 +161,6 @@ class Migration(migrations.Migration): model_name='script', constraint=models.UniqueConstraint(fields=('name', 'module'), name='extras_script_unique_name_module'), ), - migrations.RunPython( - code=update_scripts, - reverse_code=migrations.RunPython.noop - ), - migrations.RunPython( - code=update_event_rules, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=update_scripts, reverse_code=migrations.RunPython.noop), + migrations.RunPython(code=update_event_rules, reverse_code=migrations.RunPython.noop), ] diff --git a/netbox/extras/migrations/0110_remove_eventrule_action_parameters.py b/netbox/extras/migrations/0110_remove_eventrule_action_parameters.py index b7373bdce..494107643 100644 --- a/netbox/extras/migrations/0110_remove_eventrule_action_parameters.py +++ b/netbox/extras/migrations/0110_remove_eventrule_action_parameters.py @@ -2,7 +2,6 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ ('extras', '0109_script_model'), ] diff --git a/netbox/extras/migrations/0111_rename_content_types.py b/netbox/extras/migrations/0111_rename_content_types.py index acd6aef0f..a9f80b146 100644 --- a/netbox/extras/migrations/0111_rename_content_types.py +++ b/netbox/extras/migrations/0111_rename_content_types.py @@ -3,7 +3,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('core', '0010_gfk_indexes'), ('extras', '0110_remove_eventrule_action_parameters'), @@ -24,16 +23,19 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='customfield', name='object_type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='core.objecttype'), - ), - migrations.RunSQL( - "ALTER TABLE IF EXISTS extras_customfield_content_types_id_seq RENAME TO extras_customfield_object_types_id_seq" + field=models.ForeignKey( + blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='core.objecttype' + ), ), + migrations.RunSQL(( + 'ALTER TABLE IF EXISTS extras_customfield_content_types_id_seq ' + 'RENAME TO extras_customfield_object_types_id_seq' + )), # Pre-v2.10 sequence name (see #15605) - migrations.RunSQL( - "ALTER TABLE IF EXISTS extras_customfield_obj_type_id_seq RENAME TO extras_customfield_object_types_id_seq" - ), - + migrations.RunSQL(( + 'ALTER TABLE IF EXISTS extras_customfield_obj_type_id_seq ' + 'RENAME TO extras_customfield_object_types_id_seq' + )), # Custom links migrations.RenameField( model_name='customlink', @@ -46,9 +48,8 @@ class Migration(migrations.Migration): field=models.ManyToManyField(related_name='custom_links', to='core.objecttype'), ), migrations.RunSQL( - "ALTER TABLE extras_customlink_content_types_id_seq RENAME TO extras_customlink_object_types_id_seq" + 'ALTER TABLE extras_customlink_content_types_id_seq RENAME TO extras_customlink_object_types_id_seq' ), - # Event rules migrations.RenameField( model_name='eventrule', @@ -61,9 +62,8 @@ class Migration(migrations.Migration): field=models.ManyToManyField(related_name='event_rules', to='core.objecttype'), ), migrations.RunSQL( - "ALTER TABLE extras_eventrule_content_types_id_seq RENAME TO extras_eventrule_object_types_id_seq" + 'ALTER TABLE extras_eventrule_content_types_id_seq RENAME TO extras_eventrule_object_types_id_seq' ), - # Export templates migrations.RenameField( model_name='exporttemplate', @@ -76,9 +76,8 @@ class Migration(migrations.Migration): field=models.ManyToManyField(related_name='export_templates', to='core.objecttype'), ), migrations.RunSQL( - "ALTER TABLE extras_exporttemplate_content_types_id_seq RENAME TO extras_exporttemplate_object_types_id_seq" + 'ALTER TABLE extras_exporttemplate_content_types_id_seq RENAME TO extras_exporttemplate_object_types_id_seq' ), - # Saved filters migrations.RenameField( model_name='savedfilter', @@ -91,9 +90,8 @@ class Migration(migrations.Migration): field=models.ManyToManyField(related_name='saved_filters', to='core.objecttype'), ), migrations.RunSQL( - "ALTER TABLE extras_savedfilter_content_types_id_seq RENAME TO extras_savedfilter_object_types_id_seq" + 'ALTER TABLE extras_savedfilter_content_types_id_seq RENAME TO extras_savedfilter_object_types_id_seq' ), - # Image attachments migrations.RemoveIndex( model_name='imageattachment', diff --git a/netbox/extras/migrations/0112_tag_update_object_types.py b/netbox/extras/migrations/0112_tag_update_object_types.py index 87ec117a4..e863ba8c3 100644 --- a/netbox/extras/migrations/0112_tag_update_object_types.py +++ b/netbox/extras/migrations/0112_tag_update_object_types.py @@ -2,7 +2,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('core', '0010_gfk_indexes'), ('extras', '0111_rename_content_types'), diff --git a/netbox/extras/migrations/0113_customfield_rename_object_type.py b/netbox/extras/migrations/0113_customfield_rename_object_type.py index 73c4a2a61..9ad9fbbc4 100644 --- a/netbox/extras/migrations/0113_customfield_rename_object_type.py +++ b/netbox/extras/migrations/0113_customfield_rename_object_type.py @@ -2,7 +2,6 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ ('extras', '0112_tag_update_object_types'), ] diff --git a/netbox/extras/migrations/0114_customfield_add_comments.py b/netbox/extras/migrations/0114_customfield_add_comments.py index cd85db1ba..ad9e3d46f 100644 --- a/netbox/extras/migrations/0114_customfield_add_comments.py +++ b/netbox/extras/migrations/0114_customfield_add_comments.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('extras', '0113_customfield_rename_object_type'), ] diff --git a/netbox/extras/migrations/0115_convert_dashboard_widgets.py b/netbox/extras/migrations/0115_convert_dashboard_widgets.py index c85c83ecf..28f6eade9 100644 --- a/netbox/extras/migrations/0115_convert_dashboard_widgets.py +++ b/netbox/extras/migrations/0115_convert_dashboard_widgets.py @@ -16,14 +16,10 @@ def update_dashboard_widgets(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('extras', '0114_customfield_add_comments'), ] operations = [ - migrations.RunPython( - code=update_dashboard_widgets, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=update_dashboard_widgets, reverse_code=migrations.RunPython.noop), ] diff --git a/netbox/extras/migrations/0116_custom_link_button_color.py b/netbox/extras/migrations/0116_custom_link_button_color.py index 665d73017..ff47eab11 100644 --- a/netbox/extras/migrations/0116_custom_link_button_color.py +++ b/netbox/extras/migrations/0116_custom_link_button_color.py @@ -7,7 +7,6 @@ def update_link_buttons(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('extras', '0115_convert_dashboard_widgets'), ] @@ -18,8 +17,5 @@ class Migration(migrations.Migration): name='button_class', field=models.CharField(default='default', max_length=30), ), - migrations.RunPython( - code=update_link_buttons, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=update_link_buttons, reverse_code=migrations.RunPython.noop), ] diff --git a/netbox/extras/migrations/0117_move_objectchange.py b/netbox/extras/migrations/0117_move_objectchange.py index a69b5a711..62c7255e7 100644 --- a/netbox/extras/migrations/0117_move_objectchange.py +++ b/netbox/extras/migrations/0117_move_objectchange.py @@ -26,7 +26,6 @@ def update_dashboard_widgets(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('extras', '0116_custom_link_button_color'), ('core', '0011_move_objectchange'), @@ -44,81 +43,64 @@ class Migration(migrations.Migration): name='ObjectChange', table='core_objectchange', ), - # Rename PK sequence - migrations.RunSQL( - "ALTER TABLE extras_objectchange_id_seq" - " RENAME TO core_objectchange_id_seq" - ), - + migrations.RunSQL('ALTER TABLE extras_objectchange_id_seq' ' RENAME TO core_objectchange_id_seq'), # Rename indexes. Hashes generated by schema_editor._create_index_name() + migrations.RunSQL('ALTER INDEX extras_objectchange_pkey' ' RENAME TO core_objectchange_pkey'), migrations.RunSQL( - "ALTER INDEX extras_objectchange_pkey" - " RENAME TO core_objectchange_pkey" + 'ALTER INDEX extras_obje_changed_927fe5_idx' + ' RENAME TO core_objectchange_changed_object_type_id_cha_79a9ed1e' ), migrations.RunSQL( - "ALTER INDEX extras_obje_changed_927fe5_idx" - " RENAME TO core_objectchange_changed_object_type_id_cha_79a9ed1e" + 'ALTER INDEX extras_obje_related_bfcdef_idx' + ' RENAME TO core_objectchange_related_object_type_id_rel_a71d604a' ), migrations.RunSQL( - "ALTER INDEX extras_obje_related_bfcdef_idx" - " RENAME TO core_objectchange_related_object_type_id_rel_a71d604a" + 'ALTER INDEX extras_objectchange_changed_object_type_id_b755bb60' + ' RENAME TO core_objectchange_changed_object_type_id_2070ade6' ), migrations.RunSQL( - "ALTER INDEX extras_objectchange_changed_object_type_id_b755bb60" - " RENAME TO core_objectchange_changed_object_type_id_2070ade6" + 'ALTER INDEX extras_objectchange_related_object_type_id_fe6e521f' + ' RENAME TO core_objectchange_related_object_type_id_b80958af' ), migrations.RunSQL( - "ALTER INDEX extras_objectchange_related_object_type_id_fe6e521f" - " RENAME TO core_objectchange_related_object_type_id_b80958af" + 'ALTER INDEX extras_objectchange_request_id_4ae21e90' + ' RENAME TO core_objectchange_request_id_d9d160ac' ), migrations.RunSQL( - "ALTER INDEX extras_objectchange_request_id_4ae21e90" - " RENAME TO core_objectchange_request_id_d9d160ac" + 'ALTER INDEX extras_objectchange_time_224380ea' ' RENAME TO core_objectchange_time_800f60a5' ), migrations.RunSQL( - "ALTER INDEX extras_objectchange_time_224380ea" - " RENAME TO core_objectchange_time_800f60a5" + 'ALTER INDEX extras_objectchange_user_id_7fdf8186' ' RENAME TO core_objectchange_user_id_2b2142be' ), - migrations.RunSQL( - "ALTER INDEX extras_objectchange_user_id_7fdf8186" - " RENAME TO core_objectchange_user_id_2b2142be" - ), - # Rename constraints migrations.RunSQL( - "ALTER TABLE core_objectchange RENAME CONSTRAINT " - "extras_objectchange_changed_object_id_check TO " - "core_objectchange_changed_object_id_check" + 'ALTER TABLE core_objectchange RENAME CONSTRAINT ' + 'extras_objectchange_changed_object_id_check TO ' + 'core_objectchange_changed_object_id_check' ), migrations.RunSQL( - "ALTER TABLE core_objectchange RENAME CONSTRAINT " - "extras_objectchange_related_object_id_check TO " - "core_objectchange_related_object_id_check" + 'ALTER TABLE core_objectchange RENAME CONSTRAINT ' + 'extras_objectchange_related_object_id_check TO ' + 'core_objectchange_related_object_id_check' ), migrations.RunSQL( - "ALTER TABLE core_objectchange RENAME CONSTRAINT " - "extras_objectchange_changed_object_type__b755bb60_fk_django_co TO " - "core_objectchange_changed_object_type_id_2070ade6" + 'ALTER TABLE core_objectchange RENAME CONSTRAINT ' + 'extras_objectchange_changed_object_type__b755bb60_fk_django_co TO ' + 'core_objectchange_changed_object_type_id_2070ade6' ), migrations.RunSQL( - "ALTER TABLE core_objectchange RENAME CONSTRAINT " - "extras_objectchange_related_object_type__fe6e521f_fk_django_co TO " - "core_objectchange_related_object_type_id_b80958af" + 'ALTER TABLE core_objectchange RENAME CONSTRAINT ' + 'extras_objectchange_related_object_type__fe6e521f_fk_django_co TO ' + 'core_objectchange_related_object_type_id_b80958af' ), migrations.RunSQL( - "ALTER TABLE core_objectchange RENAME CONSTRAINT " - "extras_objectchange_user_id_7fdf8186_fk_auth_user_id TO " - "core_objectchange_user_id_2b2142be" + 'ALTER TABLE core_objectchange RENAME CONSTRAINT ' + 'extras_objectchange_user_id_7fdf8186_fk_auth_user_id TO ' + 'core_objectchange_user_id_2b2142be' ), ], ), - migrations.RunPython( - code=update_content_types, - reverse_code=migrations.RunPython.noop - ), - migrations.RunPython( - code=update_dashboard_widgets, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=update_content_types, reverse_code=migrations.RunPython.noop), + migrations.RunPython(code=update_dashboard_widgets, reverse_code=migrations.RunPython.noop), ] diff --git a/netbox/extras/migrations/0118_customfield_uniqueness.py b/netbox/extras/migrations/0118_customfield_uniqueness.py index b7693aa24..7571e975a 100644 --- a/netbox/extras/migrations/0118_customfield_uniqueness.py +++ b/netbox/extras/migrations/0118_customfield_uniqueness.py @@ -2,7 +2,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('extras', '0117_move_objectchange'), ] diff --git a/netbox/extras/migrations/0119_notifications.py b/netbox/extras/migrations/0119_notifications.py index c266f3b6c..2e6aefd20 100644 --- a/netbox/extras/migrations/0119_notifications.py +++ b/netbox/extras/migrations/0119_notifications.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('contenttypes', '0002_remove_content_type_name'), ('extras', '0118_customfield_uniqueness'), @@ -22,7 +21,10 @@ class Migration(migrations.Migration): ('name', models.CharField(max_length=100, unique=True)), ('description', models.CharField(blank=True, max_length=200)), ('groups', models.ManyToManyField(blank=True, related_name='notification_groups', to='users.group')), - ('users', models.ManyToManyField(blank=True, related_name='notification_groups', to=settings.AUTH_USER_MODEL)), + ( + 'users', + models.ManyToManyField(blank=True, related_name='notification_groups', to=settings.AUTH_USER_MODEL), + ), ], options={ 'verbose_name': 'notification group', @@ -36,8 +38,18 @@ class Migration(migrations.Migration): ('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.CASCADE, related_name='subscriptions', to=settings.AUTH_USER_MODEL)), + ( + 'object_type', + models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='contenttypes.contenttype'), + ), + ( + 'user', + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name='subscriptions', + to=settings.AUTH_USER_MODEL, + ), + ), ], options={ 'verbose_name': 'subscription', @@ -53,9 +65,19 @@ class Migration(migrations.Migration): ('read', models.DateTimeField(blank=True, null=True)), ('object_id', models.PositiveBigIntegerField()), ('event_type', models.CharField(max_length=50)), - ('object_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='contenttypes.contenttype')), + ( + 'object_type', + models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='contenttypes.contenttype'), + ), ('object_repr', models.CharField(editable=False, max_length=200)), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='notifications', to=settings.AUTH_USER_MODEL)), + ( + 'user', + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name='notifications', + to=settings.AUTH_USER_MODEL, + ), + ), ], options={ 'verbose_name': 'notification', @@ -66,7 +88,9 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='notification', - constraint=models.UniqueConstraint(fields=('object_type', 'object_id', 'user'), name='extras_notification_unique_per_object_and_user'), + constraint=models.UniqueConstraint( + fields=('object_type', 'object_id', 'user'), name='extras_notification_unique_per_object_and_user' + ), ), migrations.AddIndex( model_name='subscription', @@ -74,6 +98,8 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='subscription', - constraint=models.UniqueConstraint(fields=('object_type', 'object_id', 'user'), name='extras_subscription_unique_per_object_and_user'), + constraint=models.UniqueConstraint( + fields=('object_type', 'object_id', 'user'), name='extras_subscription_unique_per_object_and_user' + ), ), ] diff --git a/netbox/extras/migrations/0120_eventrule_event_types.py b/netbox/extras/migrations/0120_eventrule_event_types.py index f62c83e4c..2bcc0a4e6 100644 --- a/netbox/extras/migrations/0120_eventrule_event_types.py +++ b/netbox/extras/migrations/0120_eventrule_event_types.py @@ -26,7 +26,6 @@ def set_event_types(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('extras', '0119_notifications'), ] @@ -36,16 +35,10 @@ class Migration(migrations.Migration): model_name='eventrule', name='event_types', field=django.contrib.postgres.fields.ArrayField( - base_field=models.CharField(max_length=50), - blank=True, - null=True, - size=None + base_field=models.CharField(max_length=50), blank=True, null=True, size=None ), ), - migrations.RunPython( - code=set_event_types, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=set_event_types, reverse_code=migrations.RunPython.noop), migrations.AlterField( model_name='eventrule', name='event_types', diff --git a/netbox/extras/migrations/0121_customfield_related_object_filter.py b/netbox/extras/migrations/0121_customfield_related_object_filter.py index d6e41fd7d..10eecd6cc 100644 --- a/netbox/extras/migrations/0121_customfield_related_object_filter.py +++ b/netbox/extras/migrations/0121_customfield_related_object_filter.py @@ -2,7 +2,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('extras', '0120_eventrule_event_types'), ] diff --git a/netbox/extras/migrations/0122_charfield_null_choices.py b/netbox/extras/migrations/0122_charfield_null_choices.py index 9a1c7ff3f..a32051cb1 100644 --- a/netbox/extras/migrations/0122_charfield_null_choices.py +++ b/netbox/extras/migrations/0122_charfield_null_choices.py @@ -11,7 +11,6 @@ def set_null_values(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('extras', '0121_customfield_related_object_filter'), ] @@ -22,8 +21,5 @@ class Migration(migrations.Migration): name='base_choices', field=models.CharField(blank=True, max_length=50, null=True), ), - migrations.RunPython( - code=set_null_values, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=set_null_values, reverse_code=migrations.RunPython.noop), ] diff --git a/netbox/extras/models/models.py b/netbox/extras/models/models.py index d8a274c89..d3e443b14 100644 --- a/netbox/extras/models/models.py +++ b/netbox/extras/models/models.py @@ -704,7 +704,10 @@ class JournalEntry(CustomFieldsMixin, CustomLinksMixin, TagsMixin, ExportTemplat def __str__(self): created = timezone.localtime(self.created) - return f"{created.date().isoformat()} {created.time().isoformat(timespec='minutes')} ({self.get_kind_display()})" + return ( + f"{created.date().isoformat()} {created.time().isoformat(timespec='minutes')} " + f"({self.get_kind_display()})" + ) def get_absolute_url(self): return reverse('extras:journalentry', args=[self.pk]) diff --git a/netbox/extras/tests/test_customfields.py b/netbox/extras/tests/test_customfields.py index 2bc9b5acc..ce26cb889 100644 --- a/netbox/extras/tests/test_customfields.py +++ b/netbox/extras/tests/test_customfields.py @@ -637,15 +637,51 @@ class CustomFieldAPITest(APITestCase): ) custom_fields = ( - CustomField(type=CustomFieldTypeChoices.TYPE_TEXT, name='text_field', default='foo'), - CustomField(type=CustomFieldTypeChoices.TYPE_LONGTEXT, name='longtext_field', default='ABC'), - CustomField(type=CustomFieldTypeChoices.TYPE_INTEGER, name='integer_field', default=123), - CustomField(type=CustomFieldTypeChoices.TYPE_DECIMAL, name='decimal_field', default=123.45), - CustomField(type=CustomFieldTypeChoices.TYPE_BOOLEAN, name='boolean_field', default=False), - CustomField(type=CustomFieldTypeChoices.TYPE_DATE, name='date_field', default='2020-01-01'), - CustomField(type=CustomFieldTypeChoices.TYPE_DATETIME, name='datetime_field', default='2020-01-01T01:23:45'), - CustomField(type=CustomFieldTypeChoices.TYPE_URL, name='url_field', default='http://example.com/1'), - CustomField(type=CustomFieldTypeChoices.TYPE_JSON, name='json_field', default='{"x": "y"}'), + CustomField( + type=CustomFieldTypeChoices.TYPE_TEXT, + name='text_field', + default='foo' + ), + CustomField( + type=CustomFieldTypeChoices.TYPE_LONGTEXT, + name='longtext_field', + default='ABC' + ), + CustomField( + type=CustomFieldTypeChoices.TYPE_INTEGER, + name='integer_field', + default=123 + ), + CustomField( + type=CustomFieldTypeChoices.TYPE_DECIMAL, + name='decimal_field', + default=123.45 + ), + CustomField( + type=CustomFieldTypeChoices.TYPE_BOOLEAN, + name='boolean_field', + default=False) + , + CustomField( + type=CustomFieldTypeChoices.TYPE_DATE, + name='date_field', + default='2020-01-01' + ), + CustomField( + type=CustomFieldTypeChoices.TYPE_DATETIME, + name='datetime_field', + default='2020-01-01T01:23:45' + ), + CustomField( + type=CustomFieldTypeChoices.TYPE_URL, + name='url_field', + default='http://example.com/1' + ), + CustomField( + type=CustomFieldTypeChoices.TYPE_JSON, + name='json_field', + default='{"x": "y"}' + ), CustomField( type=CustomFieldTypeChoices.TYPE_SELECT, name='select_field', @@ -656,7 +692,7 @@ class CustomFieldAPITest(APITestCase): type=CustomFieldTypeChoices.TYPE_MULTISELECT, name='multiselect_field', default=['foo'], - choice_set=choice_set + choice_set=choice_set, ), CustomField( type=CustomFieldTypeChoices.TYPE_OBJECT, @@ -1273,9 +1309,18 @@ class CustomFieldImportTest(TestCase): Import a Site in CSV format, including a value for each CustomField. """ data = ( - ('name', 'slug', 'status', 'cf_text', 'cf_longtext', 'cf_integer', 'cf_decimal', 'cf_boolean', 'cf_date', 'cf_datetime', 'cf_url', 'cf_json', 'cf_select', 'cf_multiselect'), - ('Site 1', 'site-1', 'active', 'ABC', 'Foo', '123', '123.45', 'True', '2020-01-01', '2020-01-01 12:00:00', 'http://example.com/1', '{"foo": 123}', 'a', '"a,b"'), - ('Site 2', 'site-2', 'active', 'DEF', 'Bar', '456', '456.78', 'False', '2020-01-02', '2020-01-02 12:00:00', 'http://example.com/2', '{"bar": 456}', 'b', '"b,c"'), + ( + 'name', 'slug', 'status', 'cf_text', 'cf_longtext', 'cf_integer', 'cf_decimal', 'cf_boolean', 'cf_date', + 'cf_datetime', 'cf_url', 'cf_json', 'cf_select', 'cf_multiselect', + ), + ( + 'Site 1', 'site-1', 'active', 'ABC', 'Foo', '123', '123.45', 'True', '2020-01-01', + '2020-01-01 12:00:00', 'http://example.com/1', '{"foo": 123}', 'a', '"a,b"', + ), + ( + 'Site 2', 'site-2', 'active', 'DEF', 'Bar', '456', '456.78', 'False', '2020-01-02', + '2020-01-02 12:00:00', 'http://example.com/2', '{"bar": 456}', 'b', '"b,c"', + ), ('Site 3', 'site-3', 'active', '', '', '', '', '', '', '', '', '', '', ''), ) csv_data = '\n'.join(','.join(row) for row in data) @@ -1616,7 +1661,10 @@ class CustomFieldModelFilterTest(TestCase): self.assertEqual(self.filterset({'cf_cf6__lte': ['2016-06-27']}, self.queryset).qs.count(), 2) def test_filter_url_strict(self): - self.assertEqual(self.filterset({'cf_cf7': ['http://a.example.com', 'http://b.example.com']}, self.queryset).qs.count(), 2) + self.assertEqual( + self.filterset({'cf_cf7': ['http://a.example.com', 'http://b.example.com']}, self.queryset).qs.count(), + 2 + ) self.assertEqual(self.filterset({'cf_cf7__n': ['http://b.example.com']}, self.queryset).qs.count(), 2) self.assertEqual(self.filterset({'cf_cf7__ic': ['b']}, self.queryset).qs.count(), 1) self.assertEqual(self.filterset({'cf_cf7__nic': ['b']}, self.queryset).qs.count(), 2) @@ -1640,9 +1688,18 @@ class CustomFieldModelFilterTest(TestCase): def test_filter_object(self): manufacturer_ids = Manufacturer.objects.values_list('id', flat=True) - self.assertEqual(self.filterset({'cf_cf11': [manufacturer_ids[0], manufacturer_ids[1]]}, self.queryset).qs.count(), 2) + self.assertEqual( + self.filterset({'cf_cf11': [manufacturer_ids[0], manufacturer_ids[1]]}, self.queryset).qs.count(), + 2 + ) def test_filter_multiobject(self): manufacturer_ids = Manufacturer.objects.values_list('id', flat=True) - self.assertEqual(self.filterset({'cf_cf12': [manufacturer_ids[0], manufacturer_ids[1]]}, self.queryset).qs.count(), 2) - self.assertEqual(self.filterset({'cf_cf12': [manufacturer_ids[3]]}, self.queryset).qs.count(), 3) + self.assertEqual( + self.filterset({'cf_cf12': [manufacturer_ids[0], manufacturer_ids[1]]}, self.queryset).qs.count(), + 2 + ) + self.assertEqual( + self.filterset({'cf_cf12': [manufacturer_ids[3]]}, self.queryset).qs.count(), + 3 + ) diff --git a/netbox/ipam/forms/model_forms.py b/netbox/ipam/forms/model_forms.py index 53ffe8f3f..094da3007 100644 --- a/netbox/ipam/forms/model_forms.py +++ b/netbox/ipam/forms/model_forms.py @@ -387,7 +387,12 @@ class IPAddressForm(TenancyForm, NetBoxModelForm): }) elif selected_objects: assigned_object = self.cleaned_data[selected_objects[0]] - if self.instance.pk and self.instance.assigned_object and self.cleaned_data['primary_for_parent'] and assigned_object != self.instance.assigned_object: + if ( + self.instance.pk and + self.instance.assigned_object and + self.cleaned_data['primary_for_parent'] and + assigned_object != self.instance.assigned_object + ): raise ValidationError( _("Cannot reassign IP address while it is designated as the primary IP for the parent object") ) diff --git a/netbox/ipam/graphql/types.py b/netbox/ipam/graphql/types.py index 5a4813e0c..e6ecca984 100644 --- a/netbox/ipam/graphql/types.py +++ b/netbox/ipam/graphql/types.py @@ -295,7 +295,10 @@ class VLANTranslationPolicyType(NetBoxObjectType): filters=VLANTranslationRuleFilter ) class VLANTranslationRuleType(NetBoxObjectType): - policy: Annotated["VLANTranslationPolicyType", strawberry.lazy('ipam.graphql.types')] = strawberry_django.field(select_related=["policy"]) + policy: Annotated[ + "VLANTranslationPolicyType", + strawberry.lazy('ipam.graphql.types') + ] = strawberry_django.field(select_related=["policy"]) @strawberry_django.type( diff --git a/netbox/ipam/migrations/0001_squashed.py b/netbox/ipam/migrations/0001_squashed.py index bef36e698..896d7c4c9 100644 --- a/netbox/ipam/migrations/0001_squashed.py +++ b/netbox/ipam/migrations/0001_squashed.py @@ -9,7 +9,6 @@ import taggit.managers class Migration(migrations.Migration): - initial = True dependencies = [ @@ -50,7 +49,23 @@ class Migration(migrations.Migration): ('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_-]+)*\\.?$')])), + ( + '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={ @@ -73,7 +88,11 @@ class Migration(migrations.Migration): ], options={ 'verbose_name_plural': 'prefixes', - 'ordering': (django.db.models.expressions.OrderBy(django.db.models.expressions.F('vrf'), nulls_first=True), 'prefix', 'pk'), + 'ordering': ( + django.db.models.expressions.OrderBy(django.db.models.expressions.F('vrf'), nulls_first=True), + 'prefix', + 'pk', + ), }, ), migrations.CreateModel( @@ -135,10 +154,25 @@ class Migration(migrations.Migration): ('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')), + ( + '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')), + ( + 'tenant', + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='vrfs', + to='tenancy.tenant', + ), + ), ], options={ 'verbose_name': 'VRF', @@ -157,7 +191,21 @@ class Migration(migrations.Migration): ('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')), + ( + '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', @@ -172,15 +220,59 @@ class Migration(migrations.Migration): ('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)])), + ( + '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')), + ( + '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')), + ( + 'tenant', + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='vlans', + to='tenancy.tenant', + ), + ), ], options={ 'verbose_name': 'VLAN', @@ -197,9 +289,29 @@ class Migration(migrations.Migration): ('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)), + ( + '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')), + ( + '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')), ], diff --git a/netbox/ipam/migrations/0002_squashed_0046.py b/netbox/ipam/migrations/0002_squashed_0046.py index 06bcd8741..6c03753d8 100644 --- a/netbox/ipam/migrations/0002_squashed_0046.py +++ b/netbox/ipam/migrations/0002_squashed_0046.py @@ -4,7 +4,6 @@ import taggit.managers class Migration(migrations.Migration): - dependencies = [ ('dcim', '0003_auto_20160628_1721'), ('virtualization', '0001_virtualization'), @@ -66,7 +65,13 @@ class Migration(migrations.Migration): 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'), + 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', @@ -76,17 +81,35 @@ class Migration(migrations.Migration): 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'), + 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'), + 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'), + 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', @@ -96,27 +119,64 @@ class Migration(migrations.Migration): 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'), + 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'), + 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'), + 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'), + 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'), + 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', @@ -126,17 +186,31 @@ class Migration(migrations.Migration): 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'), + 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'), + 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'), + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, related_name='aggregates', to='ipam.rir' + ), ), migrations.AddField( model_name='aggregate', @@ -146,7 +220,13 @@ class Migration(migrations.Migration): 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'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='aggregates', + to='tenancy.tenant', + ), ), migrations.AlterUniqueTogether( name='vlangroup', diff --git a/netbox/ipam/migrations/0047_squashed_0053.py b/netbox/ipam/migrations/0047_squashed_0053.py index 470261316..a05d0cb81 100644 --- a/netbox/ipam/migrations/0047_squashed_0053.py +++ b/netbox/ipam/migrations/0047_squashed_0053.py @@ -8,7 +8,6 @@ import utilities.json class Migration(migrations.Migration): - replaces = [ ('ipam', '0047_prefix_depth_children'), ('ipam', '0048_prefix_populate_depth_children'), @@ -16,7 +15,7 @@ class Migration(migrations.Migration): ('ipam', '0050_iprange'), ('ipam', '0051_extend_tag_support'), ('ipam', '0052_fhrpgroup'), - ('ipam', '0053_asn_model') + ('ipam', '0053_asn_model'), ] dependencies = [ @@ -47,17 +46,47 @@ class Migration(migrations.Migration): 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=utilities.json.CustomFieldJSONEncoder)), + ( + 'custom_field_data', + models.JSONField(blank=True, default=dict, encoder=utilities.json.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')), + ( + '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')), + ( + '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', @@ -85,7 +114,10 @@ class Migration(migrations.Migration): 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=utilities.json.CustomFieldJSONEncoder)), + ( + 'custom_field_data', + models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder), + ), ('id', models.BigAutoField(primary_key=True, serialize=False)), ('group_id', models.PositiveSmallIntegerField()), ('protocol', models.CharField(max_length=50)), @@ -102,7 +134,21 @@ class Migration(migrations.Migration): 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'), + 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', @@ -111,9 +157,20 @@ class Migration(migrations.Migration): ('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)])), + ( + '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')), + ( + 'interface_type', + models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype'), + ), ], options={ 'verbose_name': 'FHRP group assignment', @@ -126,13 +183,28 @@ class Migration(migrations.Migration): 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=utilities.json.CustomFieldJSONEncoder)), + ( + 'custom_field_data', + models.JSONField(blank=True, default=dict, encoder=utilities.json.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')), + ( + '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')), + ( + 'tenant', + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='asns', + to='tenancy.tenant', + ), + ), ], options={ 'verbose_name': 'ASN', diff --git a/netbox/ipam/migrations/0054_squashed_0067.py b/netbox/ipam/migrations/0054_squashed_0067.py index 40073ca29..929a27fda 100644 --- a/netbox/ipam/migrations/0054_squashed_0067.py +++ b/netbox/ipam/migrations/0054_squashed_0067.py @@ -10,7 +10,6 @@ import utilities.json class Migration(migrations.Migration): - replaces = [ ('ipam', '0054_vlangroup_min_max_vids'), ('ipam', '0055_servicetemplate'), @@ -25,7 +24,7 @@ class Migration(migrations.Migration): ('ipam', '0064_clear_search_cache'), ('ipam', '0065_asnrange'), ('ipam', '0066_iprange_mark_utilized'), - ('ipam', '0067_ipaddress_index_host') + ('ipam', '0067_ipaddress_index_host'), ] dependencies = [ @@ -40,12 +39,24 @@ class Migration(migrations.Migration): migrations.AddField( model_name='vlangroup', name='max_vid', - field=models.PositiveSmallIntegerField(default=4094, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(4094)]), + 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)]), + field=models.PositiveSmallIntegerField( + default=1, + validators=[ + django.core.validators.MinValueValidator(1), + django.core.validators.MaxValueValidator(4094), + ], + ), ), migrations.AlterField( model_name='aggregate', @@ -187,10 +198,24 @@ class Migration(migrations.Migration): fields=[ ('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=utilities.json.CustomFieldJSONEncoder), + ), ('id', models.BigAutoField(auto_created=True, 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)), + ( + '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')), @@ -217,7 +242,13 @@ class Migration(migrations.Migration): 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'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name='nat_outside', + to='ipam.ipaddress', + ), ), migrations.CreateModel( name='L2VPN', @@ -225,16 +256,34 @@ class Migration(migrations.Migration): ('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=utilities.json.CustomFieldJSONEncoder), + ), ('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)), ('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')), + ( + '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')), + ( + 'tenant', + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='l2vpns', + to='tenancy.tenant', + ), + ), ], options={ 'verbose_name': 'L2VPN', @@ -247,10 +296,33 @@ class Migration(migrations.Migration): ('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=utilities.json.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')), + ( + '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={ @@ -260,7 +332,9 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='l2vpntermination', - constraint=models.UniqueConstraint(fields=('assigned_object_type', 'assigned_object_id'), name='ipam_l2vpntermination_assigned_object'), + constraint=models.UniqueConstraint( + fields=('assigned_object_type', 'assigned_object_id'), name='ipam_l2vpntermination_assigned_object' + ), ), migrations.AddField( model_name='fhrpgroup', @@ -281,7 +355,10 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='fhrpgroupassignment', - constraint=models.UniqueConstraint(fields=('interface_type', 'interface_id', 'group'), name='ipam_fhrpgroupassignment_unique_interface_group'), + constraint=models.UniqueConstraint( + fields=('interface_type', 'interface_id', 'group'), + name='ipam_fhrpgroupassignment_unique_interface_group', + ), ), migrations.AddConstraint( model_name='vlan', @@ -293,11 +370,15 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='vlangroup', - constraint=models.UniqueConstraint(fields=('scope_type', 'scope_id', 'name'), name='ipam_vlangroup_unique_scope_name'), + 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'), + constraint=models.UniqueConstraint( + fields=('scope_type', 'scope_id', 'slug'), name='ipam_vlangroup_unique_scope_slug' + ), ), migrations.AddField( model_name='aggregate', @@ -365,15 +446,32 @@ class Migration(migrations.Migration): ('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=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')), + ( + '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')), + ( + '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', @@ -388,6 +486,11 @@ class Migration(migrations.Migration): ), 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'), + 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/ipam/migrations/0068_move_l2vpn.py b/netbox/ipam/migrations/0068_move_l2vpn.py index b1a059de1..9240240bc 100644 --- a/netbox/ipam/migrations/0068_move_l2vpn.py +++ b/netbox/ipam/migrations/0068_move_l2vpn.py @@ -15,7 +15,6 @@ def update_content_types(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('ipam', '0067_ipaddress_index_host'), ] @@ -57,8 +56,5 @@ class Migration(migrations.Migration): ), ], ), - migrations.RunPython( - code=update_content_types, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=update_content_types, reverse_code=migrations.RunPython.noop), ] diff --git a/netbox/ipam/migrations/0069_gfk_indexes.py b/netbox/ipam/migrations/0069_gfk_indexes.py index 75c016102..d7ce48e35 100644 --- a/netbox/ipam/migrations/0069_gfk_indexes.py +++ b/netbox/ipam/migrations/0069_gfk_indexes.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('ipam', '0068_move_l2vpn'), ] @@ -16,7 +15,9 @@ class Migration(migrations.Migration): ), migrations.AddIndex( model_name='ipaddress', - index=models.Index(fields=['assigned_object_type', 'assigned_object_id'], name='ipam_ipaddr_assigne_890ab8_idx'), + index=models.Index( + fields=['assigned_object_type', 'assigned_object_id'], name='ipam_ipaddr_assigne_890ab8_idx' + ), ), migrations.AddIndex( model_name='vlangroup', diff --git a/netbox/ipam/migrations/0070_vlangroup_vlan_id_ranges.py b/netbox/ipam/migrations/0070_vlangroup_vlan_id_ranges.py index b01941401..133173234 100644 --- a/netbox/ipam/migrations/0070_vlangroup_vlan_id_ranges.py +++ b/netbox/ipam/migrations/0070_vlangroup_vlan_id_ranges.py @@ -12,15 +12,12 @@ def set_vid_ranges(apps, schema_editor): """ VLANGroup = apps.get_model('ipam', 'VLANGroup') for group in VLANGroup.objects.all(): - group.vid_ranges = [ - NumericRange(group.min_vid, group.max_vid, bounds='[]') - ] + group.vid_ranges = [NumericRange(group.min_vid, group.max_vid, bounds='[]')] group._total_vlan_ids = group.max_vid - group.min_vid + 1 group.save() class Migration(migrations.Migration): - dependencies = [ ('ipam', '0069_gfk_indexes'), ] @@ -32,7 +29,7 @@ class Migration(migrations.Migration): field=django.contrib.postgres.fields.ArrayField( base_field=django.contrib.postgres.fields.ranges.IntegerRangeField(), default=ipam.models.vlans.default_vid_ranges, - size=None + size=None, ), ), migrations.AddField( @@ -40,10 +37,7 @@ class Migration(migrations.Migration): name='_total_vlan_ids', field=models.PositiveBigIntegerField(default=4094), ), - migrations.RunPython( - code=set_vid_ranges, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=set_vid_ranges, reverse_code=migrations.RunPython.noop), migrations.RemoveField( model_name='vlangroup', name='max_vid', diff --git a/netbox/ipam/migrations/0071_prefix_scope.py b/netbox/ipam/migrations/0071_prefix_scope.py index d016bdb93..2ab54d023 100644 --- a/netbox/ipam/migrations/0071_prefix_scope.py +++ b/netbox/ipam/migrations/0071_prefix_scope.py @@ -11,13 +11,11 @@ def copy_site_assignments(apps, schema_editor): Site = apps.get_model('dcim', 'Site') Prefix.objects.filter(site__isnull=False).update( - scope_type=ContentType.objects.get_for_model(Site), - scope_id=models.F('site_id') + scope_type=ContentType.objects.get_for_model(Site), scope_id=models.F('site_id') ) class Migration(migrations.Migration): - dependencies = [ ('contenttypes', '0002_remove_content_type_name'), ('ipam', '0070_vlangroup_vlan_id_ranges'), @@ -39,13 +37,9 @@ class Migration(migrations.Migration): null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', - to='contenttypes.contenttype' + to='contenttypes.contenttype', ), ), - # Copy over existing site assignments - migrations.RunPython( - code=copy_site_assignments, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=copy_site_assignments, reverse_code=migrations.RunPython.noop), ] diff --git a/netbox/ipam/migrations/0072_prefix_cached_relations.py b/netbox/ipam/migrations/0072_prefix_cached_relations.py index 4b438f7d5..e4a789704 100644 --- a/netbox/ipam/migrations/0072_prefix_cached_relations.py +++ b/netbox/ipam/migrations/0072_prefix_cached_relations.py @@ -19,7 +19,6 @@ def populate_denormalized_fields(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('dcim', '0193_poweroutlet_color'), ('ipam', '0071_prefix_scope'), @@ -29,12 +28,16 @@ class Migration(migrations.Migration): migrations.AddField( model_name='prefix', name='_location', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dcim.location'), + field=models.ForeignKey( + blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dcim.location' + ), ), migrations.AddField( model_name='prefix', name='_region', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dcim.region'), + field=models.ForeignKey( + blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dcim.region' + ), ), migrations.AddField( model_name='prefix', @@ -44,15 +47,12 @@ class Migration(migrations.Migration): migrations.AddField( model_name='prefix', name='_site_group', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dcim.sitegroup'), + field=models.ForeignKey( + blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dcim.sitegroup' + ), ), - # Populate denormalized FK values - migrations.RunPython( - code=populate_denormalized_fields, - reverse_code=migrations.RunPython.noop - ), - + migrations.RunPython(code=populate_denormalized_fields, reverse_code=migrations.RunPython.noop), # Delete the site ForeignKey migrations.RemoveField( model_name='prefix', diff --git a/netbox/ipam/migrations/0073_charfield_null_choices.py b/netbox/ipam/migrations/0073_charfield_null_choices.py index 9293728f5..cfb764b46 100644 --- a/netbox/ipam/migrations/0073_charfield_null_choices.py +++ b/netbox/ipam/migrations/0073_charfield_null_choices.py @@ -13,7 +13,6 @@ def set_null_values(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('ipam', '0072_prefix_cached_relations'), ] @@ -29,8 +28,5 @@ class Migration(migrations.Migration): name='role', field=models.CharField(blank=True, max_length=50, null=True), ), - migrations.RunPython( - code=set_null_values, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=set_null_values, reverse_code=migrations.RunPython.noop), ] diff --git a/netbox/ipam/migrations/0074_vlantranslationpolicy_vlantranslationrule.py b/netbox/ipam/migrations/0074_vlantranslationpolicy_vlantranslationrule.py index ca3943649..5a13f18e6 100644 --- a/netbox/ipam/migrations/0074_vlantranslationpolicy_vlantranslationrule.py +++ b/netbox/ipam/migrations/0074_vlantranslationpolicy_vlantranslationrule.py @@ -8,7 +8,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('extras', '0121_customfield_related_object_filter'), ('ipam', '0073_charfield_null_choices'), @@ -21,7 +20,10 @@ class Migration(migrations.Migration): ('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=utilities.json.CustomFieldJSONEncoder), + ), ('comments', models.TextField(blank=True)), ('name', models.CharField(max_length=100, unique=True)), ('description', models.CharField(blank=True, max_length=200)), @@ -39,24 +41,57 @@ class Migration(migrations.Migration): ('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)), - ('local_vid', models.PositiveSmallIntegerField(validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(4094)])), - ('remote_vid', models.PositiveSmallIntegerField(validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(4094)])), - ('policy', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rules', to='ipam.vlantranslationpolicy')), + ( + 'custom_field_data', + models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder), + ), + ( + 'local_vid', + models.PositiveSmallIntegerField( + validators=[ + django.core.validators.MinValueValidator(1), + django.core.validators.MaxValueValidator(4094), + ] + ), + ), + ( + 'remote_vid', + models.PositiveSmallIntegerField( + validators=[ + django.core.validators.MinValueValidator(1), + django.core.validators.MaxValueValidator(4094), + ] + ), + ), + ( + 'policy', + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name='rules', + to='ipam.vlantranslationpolicy', + ), + ), ('description', models.CharField(blank=True, max_length=200)), ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), ], options={ 'verbose_name': 'VLAN translation rule', - 'ordering': ('policy', 'local_vid',), + 'ordering': ( + 'policy', + 'local_vid', + ), }, ), migrations.AddConstraint( model_name='vlantranslationrule', - constraint=models.UniqueConstraint(fields=('policy', 'local_vid'), name='ipam_vlantranslationrule_unique_policy_local_vid'), + constraint=models.UniqueConstraint( + fields=('policy', 'local_vid'), name='ipam_vlantranslationrule_unique_policy_local_vid' + ), ), migrations.AddConstraint( model_name='vlantranslationrule', - constraint=models.UniqueConstraint(fields=('policy', 'remote_vid'), name='ipam_vlantranslationrule_unique_policy_remote_vid'), + constraint=models.UniqueConstraint( + fields=('policy', 'remote_vid'), name='ipam_vlantranslationrule_unique_policy_remote_vid' + ), ), ] diff --git a/netbox/ipam/migrations/0075_vlan_qinq.py b/netbox/ipam/migrations/0075_vlan_qinq.py index 8a3b8a39a..1e8f86c36 100644 --- a/netbox/ipam/migrations/0075_vlan_qinq.py +++ b/netbox/ipam/migrations/0075_vlan_qinq.py @@ -3,7 +3,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('ipam', '0074_vlantranslationpolicy_vlantranslationrule'), ] @@ -17,7 +16,13 @@ class Migration(migrations.Migration): migrations.AddField( model_name='vlan', name='qinq_svlan', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='qinq_cvlans', to='ipam.vlan'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='qinq_cvlans', + to='ipam.vlan', + ), ), migrations.AddConstraint( model_name='vlan', diff --git a/netbox/ipam/migrations/0076_natural_ordering.py b/netbox/ipam/migrations/0076_natural_ordering.py index 8c7bfaea1..f6c9e5ccb 100644 --- a/netbox/ipam/migrations/0076_natural_ordering.py +++ b/netbox/ipam/migrations/0076_natural_ordering.py @@ -2,7 +2,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('ipam', '0075_vlan_qinq'), ('dcim', '0197_natural_sort_collation'), diff --git a/netbox/ipam/models/ip.py b/netbox/ipam/models/ip.py index dcecbcdea..e1a8d91e3 100644 --- a/netbox/ipam/models/ip.py +++ b/netbox/ipam/models/ip.py @@ -418,7 +418,9 @@ class Prefix(ContactsMixin, GetAvailablePrefixesMixin, CachedScopeMixin, Primary available_ips = prefix - child_ips - netaddr.IPSet(child_ranges) # IPv6 /127's, pool, or IPv4 /31-/32 sets are fully usable - if (self.family == 6 and self.prefix.prefixlen >= 127) or self.is_pool or (self.family == 4 and self.prefix.prefixlen >= 31): + if (self.family == 6 and self.prefix.prefixlen >= 127) or self.is_pool or ( + self.family == 4 and self.prefix.prefixlen >= 31 + ): return available_ips if self.family == 4: @@ -561,10 +563,26 @@ class IPRange(ContactsMixin, PrimaryModel): }) # Check for overlapping ranges - overlapping_ranges = IPRange.objects.exclude(pk=self.pk).filter(vrf=self.vrf).filter( - Q(start_address__host__inet__gte=self.start_address.ip, start_address__host__inet__lte=self.end_address.ip) | # Starts inside - Q(end_address__host__inet__gte=self.start_address.ip, end_address__host__inet__lte=self.end_address.ip) | # Ends inside - Q(start_address__host__inet__lte=self.start_address.ip, end_address__host__inet__gte=self.end_address.ip) # Starts & ends outside + overlapping_ranges = ( + IPRange.objects.exclude(pk=self.pk) + .filter(vrf=self.vrf) + .filter( + # Starts inside + Q( + start_address__host__inet__gte=self.start_address.ip, + start_address__host__inet__lte=self.end_address.ip, + ) | + # Ends inside + Q( + end_address__host__inet__gte=self.start_address.ip, + end_address__host__inet__lte=self.end_address.ip, + ) | + # Starts & ends outside + Q( + start_address__host__inet__lte=self.start_address.ip, + end_address__host__inet__gte=self.end_address.ip, + ) + ) ) if overlapping_ranges.exists(): raise ValidationError( @@ -866,10 +884,12 @@ class IPAddress(ContactsMixin, PrimaryModel): # can't use is_primary_ip as self.assigned_object might be changed is_primary = False - if self.family == 4 and hasattr(original_parent, 'primary_ip4') and original_parent.primary_ip4_id == self.pk: - is_primary = True - if self.family == 6 and hasattr(original_parent, 'primary_ip6') and original_parent.primary_ip6_id == self.pk: - is_primary = True + if self.family == 4 and hasattr(original_parent, 'primary_ip4'): + if original_parent.primary_ip4_id == self.pk: + is_primary = True + if self.family == 6 and hasattr(original_parent, 'primary_ip6'): + if original_parent.primary_ip6_id == self.pk: + is_primary = True if is_primary and (parent != original_parent): raise ValidationError( diff --git a/netbox/ipam/tables/ip.py b/netbox/ipam/tables/ip.py index 399641422..dbbeb3454 100644 --- a/netbox/ipam/tables/ip.py +++ b/netbox/ipam/tables/ip.py @@ -6,6 +6,7 @@ from django_tables2.utils import Accessor from ipam.models import * from netbox.tables import NetBoxTable, columns from tenancy.tables import TenancyColumnsMixin, TenantColumn +from .template_code import * __all__ = ( 'AggregateTable', @@ -20,61 +21,6 @@ __all__ = ( AVAILABLE_LABEL = mark_safe('Available') -AGGREGATE_COPY_BUTTON = """ -{% copy_content record.pk prefix="aggregate_" %} -""" - -PREFIX_LINK = """ -{% if record.pk %} - {{ record.prefix }} -{% else %} - {{ record.prefix }} -{% endif %} -""" - -PREFIX_COPY_BUTTON = """ -{% copy_content record.pk prefix="prefix_" %} -""" - -PREFIX_LINK_WITH_DEPTH = """ -{% load helpers %} -{% if record.depth %} -
- {% for i in record.depth|as_range %} - • - {% endfor %} -
-{% endif %} -""" + PREFIX_LINK - -IPADDRESS_LINK = """ -{% if record.pk %} - {{ record.address }} -{% elif perms.ipam.add_ipaddress %} - {% if record.0 <= 65536 %}{{ record.0 }}{% else %}Many{% endif %} IP{{ record.0|pluralize }} available -{% else %} - {% if record.0 <= 65536 %}{{ record.0 }}{% else %}Many{% endif %} IP{{ record.0|pluralize }} available -{% endif %} -""" - -IPADDRESS_COPY_BUTTON = """ -{% copy_content record.pk prefix="ipaddress_" %} -""" - -IPADDRESS_ASSIGN_LINK = """ -{{ record }} -""" - -VRF_LINK = """ -{% if value %} - {{ record.vrf }} -{% elif object.vrf %} - {{ object.vrf }} -{% else %} - Global -{% endif %} -""" - # # RIRs diff --git a/netbox/ipam/tables/template_code.py b/netbox/ipam/tables/template_code.py new file mode 100644 index 000000000..fb969345e --- /dev/null +++ b/netbox/ipam/tables/template_code.py @@ -0,0 +1,88 @@ +AGGREGATE_COPY_BUTTON = """ +{% copy_content record.pk prefix="aggregate_" %} +""" + +PREFIX_LINK = """ +{% if record.pk %} + {{ record.prefix }} +{% else %} + {{ record.prefix }} +{% endif %} +""" + +PREFIX_COPY_BUTTON = """ +{% copy_content record.pk prefix="prefix_" %} +""" + +PREFIX_LINK_WITH_DEPTH = """ +{% load helpers %} +{% if record.depth %} +
+ {% for i in record.depth|as_range %} + • + {% endfor %} +
+{% endif %} +""" + PREFIX_LINK + +IPADDRESS_LINK = """ +{% if record.pk %} + {{ record.address }} +{% elif perms.ipam.add_ipaddress %} + {% if record.0 <= 65536 %}{{ record.0 }}{% else %}Many{% endif %} IP{{ record.0|pluralize }} available +{% else %} + {% if record.0 <= 65536 %}{{ record.0 }}{% else %}Many{% endif %} IP{{ record.0|pluralize }} available +{% endif %} +""" + +IPADDRESS_COPY_BUTTON = """ +{% copy_content record.pk prefix="ipaddress_" %} +""" + +IPADDRESS_ASSIGN_LINK = """ +{{ record }} +""" + +VRF_LINK = """ +{% if value %} + {{ record.vrf }} +{% elif object.vrf %} + {{ object.vrf }} +{% else %} + Global +{% endif %} +""" + +VLAN_LINK = """ +{% if record.pk %} + {{ record.vid }} +{% elif perms.ipam.add_vlan %} + {{ record.available }} VLAN{{ record.available|pluralize }} available +{% else %} + {{ record.available }} VLAN{{ record.available|pluralize }} available +{% endif %} +""" + +VLAN_PREFIXES = """ +{% for prefix in value.all %} + {{ prefix }}{% if not forloop.last %}
{% endif %} +{% endfor %} +""" + +VLANGROUP_BUTTONS = """ +{% with next_vid=record.get_next_available_vid %} + {% if next_vid and perms.ipam.add_vlan %} + + + + {% endif %} +{% endwith %} +""" + +VLAN_MEMBER_TAGGED = """ +{% if record.untagged_vlan_id == object.pk %} + +{% else %} + +{% endif %} +""" diff --git a/netbox/ipam/tables/vlans.py b/netbox/ipam/tables/vlans.py index d34ff5f45..e3d7c7e63 100644 --- a/netbox/ipam/tables/vlans.py +++ b/netbox/ipam/tables/vlans.py @@ -8,6 +8,7 @@ from ipam.models import * from netbox.tables import NetBoxTable, columns from tenancy.tables import TenancyColumnsMixin, TenantColumn from virtualization.models import VMInterface +from .template_code import * __all__ = ( 'InterfaceVLANTable', @@ -22,40 +23,6 @@ __all__ = ( AVAILABLE_LABEL = mark_safe('Available') -VLAN_LINK = """ -{% if record.pk %} - {{ record.vid }} -{% elif perms.ipam.add_vlan %} - {{ record.available }} VLAN{{ record.available|pluralize }} available -{% else %} - {{ record.available }} VLAN{{ record.available|pluralize }} available -{% endif %} -""" - -VLAN_PREFIXES = """ -{% for prefix in value.all %} - {{ prefix }}{% if not forloop.last %}
{% endif %} -{% endfor %} -""" - -VLANGROUP_BUTTONS = """ -{% with next_vid=record.get_next_available_vid %} - {% if next_vid and perms.ipam.add_vlan %} - - - - {% endif %} -{% endwith %} -""" - -VLAN_MEMBER_TAGGED = """ -{% if record.untagged_vlan_id == object.pk %} - -{% else %} - -{% endif %} -""" - # # VLAN groups diff --git a/netbox/ipam/tests/test_api.py b/netbox/ipam/tests/test_api.py index 4e8456e5a..cbcb2e7c8 100644 --- a/netbox/ipam/tests/test_api.py +++ b/netbox/ipam/tests/test_api.py @@ -732,10 +732,19 @@ class FHRPGroupTest(APIViewTestCases.APIViewTestCase): @classmethod def setUpTestData(cls): - fhrp_groups = ( - FHRPGroup(protocol=FHRPGroupProtocolChoices.PROTOCOL_VRRP2, group_id=10, auth_type=FHRPGroupAuthTypeChoices.AUTHENTICATION_PLAINTEXT, auth_key='foobar123'), - FHRPGroup(protocol=FHRPGroupProtocolChoices.PROTOCOL_VRRP3, group_id=20, auth_type=FHRPGroupAuthTypeChoices.AUTHENTICATION_MD5, auth_key='foobar123'), + FHRPGroup( + protocol=FHRPGroupProtocolChoices.PROTOCOL_VRRP2, + group_id=10, + auth_type=FHRPGroupAuthTypeChoices.AUTHENTICATION_PLAINTEXT, + auth_key='foobar123', + ), + FHRPGroup( + protocol=FHRPGroupProtocolChoices.PROTOCOL_VRRP3, + group_id=20, + auth_type=FHRPGroupAuthTypeChoices.AUTHENTICATION_MD5, + auth_key='foobar123', + ), FHRPGroup(protocol=FHRPGroupProtocolChoices.PROTOCOL_HSRP, group_id=30), ) FHRPGroup.objects.bulk_create(fhrp_groups) diff --git a/netbox/ipam/tests/test_filtersets.py b/netbox/ipam/tests/test_filtersets.py index 28e8cda1e..5455beb9c 100644 --- a/netbox/ipam/tests/test_filtersets.py +++ b/netbox/ipam/tests/test_filtersets.py @@ -496,8 +496,12 @@ class AggregateTestCase(TestCase, ChangeLoggedFilterSetTests): Tenant.objects.bulk_create(tenants) aggregates = ( - Aggregate(prefix='10.1.0.0/16', rir=rirs[0], tenant=tenants[0], date_added='2020-01-01', description='foobar1'), - Aggregate(prefix='10.2.0.0/16', rir=rirs[0], tenant=tenants[1], date_added='2020-01-02', description='foobar2'), + Aggregate( + prefix='10.1.0.0/16', rir=rirs[0], tenant=tenants[0], date_added='2020-01-01', description='foobar1' + ), + Aggregate( + prefix='10.2.0.0/16', rir=rirs[0], tenant=tenants[1], date_added='2020-01-02', description='foobar2' + ), Aggregate(prefix='10.3.0.0/16', rir=rirs[1], tenant=tenants[2], date_added='2020-01-03'), Aggregate(prefix='2001:db8:1::/48', rir=rirs[1], tenant=tenants[0], date_added='2020-01-04'), Aggregate(prefix='2001:db8:2::/48', rir=rirs[2], tenant=tenants[1], date_added='2020-01-05'), @@ -656,14 +660,80 @@ class PrefixTestCase(TestCase, ChangeLoggedFilterSetTests): Tenant.objects.bulk_create(tenants) prefixes = ( - Prefix(prefix='10.0.0.0/24', tenant=None, scope=None, vrf=None, vlan=None, role=None, is_pool=True, mark_utilized=True, description='foobar1'), - Prefix(prefix='10.0.1.0/24', tenant=tenants[0], scope=sites[0], vrf=vrfs[0], vlan=vlans[0], role=roles[0], description='foobar2'), - Prefix(prefix='10.0.2.0/24', tenant=tenants[1], scope=sites[1], vrf=vrfs[1], vlan=vlans[1], role=roles[1], status=PrefixStatusChoices.STATUS_DEPRECATED), - Prefix(prefix='10.0.3.0/24', tenant=tenants[2], scope=sites[2], vrf=vrfs[2], vlan=vlans[2], role=roles[2], status=PrefixStatusChoices.STATUS_RESERVED), - Prefix(prefix='2001:db8::/64', tenant=None, scope=None, vrf=None, vlan=None, role=None, is_pool=True, mark_utilized=True), - Prefix(prefix='2001:db8:0:1::/64', tenant=tenants[0], scope=sites[0], vrf=vrfs[0], vlan=vlans[0], role=roles[0]), - Prefix(prefix='2001:db8:0:2::/64', tenant=tenants[1], scope=sites[1], vrf=vrfs[1], vlan=vlans[1], role=roles[1], status=PrefixStatusChoices.STATUS_DEPRECATED), - Prefix(prefix='2001:db8:0:3::/64', tenant=tenants[2], scope=sites[2], vrf=vrfs[2], vlan=vlans[2], role=roles[2], status=PrefixStatusChoices.STATUS_RESERVED), + Prefix( + prefix='10.0.0.0/24', + tenant=None, + scope=None, + vrf=None, + vlan=None, + role=None, + is_pool=True, + mark_utilized=True, + description='foobar1', + ), + Prefix( + prefix='10.0.1.0/24', + tenant=tenants[0], + scope=sites[0], + vrf=vrfs[0], + vlan=vlans[0], + role=roles[0], + description='foobar2', + ), + Prefix( + prefix='10.0.2.0/24', + tenant=tenants[1], + scope=sites[1], + vrf=vrfs[1], + vlan=vlans[1], + role=roles[1], + status=PrefixStatusChoices.STATUS_DEPRECATED, + ), + Prefix( + prefix='10.0.3.0/24', + tenant=tenants[2], + scope=sites[2], + vrf=vrfs[2], + vlan=vlans[2], + role=roles[2], + status=PrefixStatusChoices.STATUS_RESERVED, + ), + Prefix( + prefix='2001:db8::/64', + tenant=None, + scope=None, + vrf=None, + vlan=None, + role=None, + is_pool=True, + mark_utilized=True, + ), + Prefix( + prefix='2001:db8:0:1::/64', + tenant=tenants[0], + scope=sites[0], + vrf=vrfs[0], + vlan=vlans[0], + role=roles[0] + ), + Prefix( + prefix='2001:db8:0:2::/64', + tenant=tenants[1], + scope=sites[1], + vrf=vrfs[1], + vlan=vlans[1], + role=roles[1], + status=PrefixStatusChoices.STATUS_DEPRECATED, + ), + Prefix( + prefix='2001:db8:0:3::/64', + tenant=tenants[2], + scope=sites[2], + vrf=vrfs[2], + vlan=vlans[2], + role=roles[2], + status=PrefixStatusChoices.STATUS_RESERVED, + ), Prefix(prefix='10.0.0.0/16'), Prefix(prefix='2001:db8::/32'), ) @@ -1365,7 +1435,10 @@ class FHRPGroupTestCase(TestCase, ChangeLoggedFilterSetTests): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_auth_type(self): - params = {'auth_type': [FHRPGroupAuthTypeChoices.AUTHENTICATION_PLAINTEXT, FHRPGroupAuthTypeChoices.AUTHENTICATION_MD5]} + params = {'auth_type': [ + FHRPGroupAuthTypeChoices.AUTHENTICATION_PLAINTEXT, + FHRPGroupAuthTypeChoices.AUTHENTICATION_MD5, + ]} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_auth_key(self): @@ -1653,9 +1726,15 @@ class VLANTestCase(TestCase, ChangeLoggedFilterSetTests): device_type = DeviceType.objects.create(manufacturer=manufacturer, model='Device Type 1') role = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1') devices = ( - Device(name='Device 1', site=sites[0], location=locations[0], rack=racks[0], device_type=device_type, role=role), - Device(name='Device 2', site=sites[1], location=locations[1], rack=racks[1], device_type=device_type, role=role), - Device(name='Device 3', site=sites[2], location=locations[2], rack=racks[2], device_type=device_type, role=role), + Device( + name='Device 1', site=sites[0], location=locations[0], rack=racks[0], device_type=device_type, role=role + ), + Device( + name='Device 2', site=sites[1], location=locations[1], rack=racks[1], device_type=device_type, role=role + ), + Device( + name='Device 3', site=sites[2], location=locations[2], rack=racks[2], device_type=device_type, role=role + ), ) Device.objects.bulk_create(devices) @@ -1773,20 +1852,64 @@ class VLANTestCase(TestCase, ChangeLoggedFilterSetTests): VLAN(vid=19, name='Cluster 1', group=groups[18]), VLAN(vid=20, name='Cluster 2', group=groups[19]), VLAN(vid=21, name='Cluster 3', group=groups[20]), - - VLAN(vid=101, name='VLAN 101', site=sites[3], group=groups[21], role=roles[0], tenant=tenants[0], status=VLANStatusChoices.STATUS_ACTIVE), - VLAN(vid=102, name='VLAN 102', site=sites[3], group=groups[21], role=roles[0], tenant=tenants[0], status=VLANStatusChoices.STATUS_ACTIVE), - VLAN(vid=201, name='VLAN 201', site=sites[4], group=groups[22], role=roles[1], tenant=tenants[1], status=VLANStatusChoices.STATUS_DEPRECATED), - VLAN(vid=202, name='VLAN 202', site=sites[4], group=groups[22], role=roles[1], tenant=tenants[1], status=VLANStatusChoices.STATUS_DEPRECATED), - VLAN(vid=301, name='VLAN 301', site=sites[5], group=groups[23], role=roles[2], tenant=tenants[2], status=VLANStatusChoices.STATUS_RESERVED), - VLAN(vid=302, name='VLAN 302', site=sites[5], group=groups[23], role=roles[2], tenant=tenants[2], status=VLANStatusChoices.STATUS_RESERVED), - + VLAN( + vid=101, + name='VLAN 101', + site=sites[3], + group=groups[21], + role=roles[0], + tenant=tenants[0], + status=VLANStatusChoices.STATUS_ACTIVE, + ), + VLAN( + vid=102, + name='VLAN 102', + site=sites[3], + group=groups[21], + role=roles[0], + tenant=tenants[0], + status=VLANStatusChoices.STATUS_ACTIVE, + ), + VLAN( + vid=201, + name='VLAN 201', + site=sites[4], + group=groups[22], + role=roles[1], + tenant=tenants[1], + status=VLANStatusChoices.STATUS_DEPRECATED, + ), + VLAN( + vid=202, + name='VLAN 202', + site=sites[4], + group=groups[22], + role=roles[1], + tenant=tenants[1], + status=VLANStatusChoices.STATUS_DEPRECATED, + ), + VLAN( + vid=301, + name='VLAN 301', + site=sites[5], + group=groups[23], + role=roles[2], + tenant=tenants[2], + status=VLANStatusChoices.STATUS_RESERVED, + ), + VLAN( + vid=302, + name='VLAN 302', + site=sites[5], + group=groups[23], + role=roles[2], + tenant=tenants[2], + status=VLANStatusChoices.STATUS_RESERVED, + ), # Create one globally available VLAN on a VLAN group VLAN(vid=500, name='VLAN Group 1', group=groups[24]), - # Create one globally available VLAN VLAN(vid=1000, name='Global VLAN'), - # Create some Q-in-Q service VLANs VLAN(vid=2001, name='SVLAN 1', site=sites[6], qinq_role=VLANQinQRoleChoices.ROLE_SERVICE), VLAN(vid=2002, name='SVLAN 2', site=sites[6], qinq_role=VLANQinQRoleChoices.ROLE_SERVICE), @@ -1795,11 +1918,31 @@ class VLANTestCase(TestCase, ChangeLoggedFilterSetTests): VLAN.objects.bulk_create(vlans) # Create Q-in-Q customer VLANs - VLAN.objects.bulk_create([ - VLAN(vid=3001, name='CVLAN 1', site=sites[6], qinq_svlan=vlans[29], qinq_role=VLANQinQRoleChoices.ROLE_CUSTOMER), - VLAN(vid=3002, name='CVLAN 2', site=sites[6], qinq_svlan=vlans[30], qinq_role=VLANQinQRoleChoices.ROLE_CUSTOMER), - VLAN(vid=3003, name='CVLAN 3', site=sites[6], qinq_svlan=vlans[31], qinq_role=VLANQinQRoleChoices.ROLE_CUSTOMER), - ]) + VLAN.objects.bulk_create( + [ + VLAN( + vid=3001, + name='CVLAN 1', + site=sites[6], + qinq_svlan=vlans[29], + qinq_role=VLANQinQRoleChoices.ROLE_CUSTOMER, + ), + VLAN( + vid=3002, + name='CVLAN 2', + site=sites[6], + qinq_svlan=vlans[30], + qinq_role=VLANQinQRoleChoices.ROLE_CUSTOMER, + ), + VLAN( + vid=3003, + name='CVLAN 3', + site=sites[6], + qinq_svlan=vlans[31], + qinq_role=VLANQinQRoleChoices.ROLE_CUSTOMER, + ), + ] + ) # Assign VLANs to device interfaces interfaces[0].untagged_vlan = vlans[0] @@ -2125,12 +2268,39 @@ class ServiceTestCase(TestCase, ChangeLoggedFilterSetTests): VirtualMachine.objects.bulk_create(virtual_machines) services = ( - Service(device=devices[0], name='Service 1', protocol=ServiceProtocolChoices.PROTOCOL_TCP, ports=[1001], description='foobar1'), - Service(device=devices[1], name='Service 2', protocol=ServiceProtocolChoices.PROTOCOL_TCP, ports=[1002], description='foobar2'), + Service( + device=devices[0], + name='Service 1', + protocol=ServiceProtocolChoices.PROTOCOL_TCP, + ports=[1001], + description='foobar1', + ), + Service( + device=devices[1], + name='Service 2', + protocol=ServiceProtocolChoices.PROTOCOL_TCP, + ports=[1002], + description='foobar2', + ), Service(device=devices[2], name='Service 3', protocol=ServiceProtocolChoices.PROTOCOL_UDP, ports=[1003]), - Service(virtual_machine=virtual_machines[0], name='Service 4', protocol=ServiceProtocolChoices.PROTOCOL_TCP, ports=[2001]), - Service(virtual_machine=virtual_machines[1], name='Service 5', protocol=ServiceProtocolChoices.PROTOCOL_TCP, ports=[2002]), - Service(virtual_machine=virtual_machines[2], name='Service 6', protocol=ServiceProtocolChoices.PROTOCOL_UDP, ports=[2003]), + Service( + virtual_machine=virtual_machines[0], + name='Service 4', + protocol=ServiceProtocolChoices.PROTOCOL_TCP, + ports=[2001], + ), + Service( + virtual_machine=virtual_machines[1], + name='Service 5', + protocol=ServiceProtocolChoices.PROTOCOL_TCP, + ports=[2002], + ), + Service( + virtual_machine=virtual_machines[2], + name='Service 6', + protocol=ServiceProtocolChoices.PROTOCOL_UDP, + ports=[2003], + ), ) Service.objects.bulk_create(services) services[0].ipaddresses.add(ip_addresses[0]) diff --git a/netbox/ipam/tests/test_models.py b/netbox/ipam/tests/test_models.py index 917b50f33..62eb74123 100644 --- a/netbox/ipam/tests/test_models.py +++ b/netbox/ipam/tests/test_models.py @@ -39,29 +39,50 @@ class TestAggregate(TestCase): class TestIPRange(TestCase): def test_overlapping_range(self): - iprange_192_168 = IPRange.objects.create(start_address=IPNetwork('192.168.0.1/22'), end_address=IPNetwork('192.168.0.49/22')) + iprange_192_168 = IPRange.objects.create( + start_address=IPNetwork('192.168.0.1/22'), end_address=IPNetwork('192.168.0.49/22') + ) iprange_192_168.clean() - iprange_3_1_99 = IPRange.objects.create(start_address=IPNetwork('1.2.3.1/24'), end_address=IPNetwork('1.2.3.99/24')) + iprange_3_1_99 = IPRange.objects.create( + start_address=IPNetwork('1.2.3.1/24'), end_address=IPNetwork('1.2.3.99/24') + ) iprange_3_1_99.clean() - iprange_3_100_199 = IPRange.objects.create(start_address=IPNetwork('1.2.3.100/24'), end_address=IPNetwork('1.2.3.199/24')) + iprange_3_100_199 = IPRange.objects.create( + start_address=IPNetwork('1.2.3.100/24'), end_address=IPNetwork('1.2.3.199/24') + ) iprange_3_100_199.clean() - iprange_3_200_255 = IPRange.objects.create(start_address=IPNetwork('1.2.3.200/24'), end_address=IPNetwork('1.2.3.255/24')) + iprange_3_200_255 = IPRange.objects.create( + start_address=IPNetwork('1.2.3.200/24'), end_address=IPNetwork('1.2.3.255/24') + ) iprange_3_200_255.clean() - iprange_4_1_99 = IPRange.objects.create(start_address=IPNetwork('1.2.4.1/24'), end_address=IPNetwork('1.2.4.99/24')) + iprange_4_1_99 = IPRange.objects.create( + start_address=IPNetwork('1.2.4.1/24'), end_address=IPNetwork('1.2.4.99/24') + ) iprange_4_1_99.clean() - iprange_4_200 = IPRange.objects.create(start_address=IPNetwork('1.2.4.200/24'), end_address=IPNetwork('1.2.4.255/24')) + iprange_4_200 = IPRange.objects.create( + start_address=IPNetwork('1.2.4.200/24'), end_address=IPNetwork('1.2.4.255/24') + ) iprange_4_200.clean() + # Overlapping range entirely within existing with self.assertRaises(ValidationError): - iprange_3_123_124 = IPRange.objects.create(start_address=IPNetwork('1.2.3.123/26'), end_address=IPNetwork('1.2.3.124/26')) + iprange_3_123_124 = IPRange.objects.create( + start_address=IPNetwork('1.2.3.123/26'), end_address=IPNetwork('1.2.3.124/26') + ) iprange_3_123_124.clean() + # Overlapping range starting within existing with self.assertRaises(ValidationError): - iprange_4_98_101 = IPRange.objects.create(start_address=IPNetwork('1.2.4.98/24'), end_address=IPNetwork('1.2.4.101/24')) + iprange_4_98_101 = IPRange.objects.create( + start_address=IPNetwork('1.2.4.98/24'), end_address=IPNetwork('1.2.4.101/24') + ) iprange_4_98_101.clean() + # Overlapping range ending within existing with self.assertRaises(ValidationError): - iprange_4_198_201 = IPRange.objects.create(start_address=IPNetwork('1.2.4.198/24'), end_address=IPNetwork('1.2.4.201/24')) + iprange_4_198_201 = IPRange.objects.create( + start_address=IPNetwork('1.2.4.198/24'), end_address=IPNetwork('1.2.4.201/24') + ) iprange_4_198_201.clean() @@ -105,13 +126,30 @@ class TestPrefix(TestCase): def test_get_child_ranges(self): prefix = Prefix(prefix='192.168.0.16/28') prefix.save() - ranges = IPRange.objects.bulk_create(( - IPRange(start_address=IPNetwork('192.168.0.1/24'), end_address=IPNetwork('192.168.0.10/24'), size=10), # No overlap - IPRange(start_address=IPNetwork('192.168.0.11/24'), end_address=IPNetwork('192.168.0.17/24'), size=7), # Partial overlap - IPRange(start_address=IPNetwork('192.168.0.18/24'), end_address=IPNetwork('192.168.0.23/24'), size=6), # Full overlap - IPRange(start_address=IPNetwork('192.168.0.24/24'), end_address=IPNetwork('192.168.0.30/24'), size=7), # Full overlap - IPRange(start_address=IPNetwork('192.168.0.31/24'), end_address=IPNetwork('192.168.0.40/24'), size=10), # Partial overlap - )) + ranges = IPRange.objects.bulk_create( + ( + # No overlap + IPRange( + start_address=IPNetwork('192.168.0.1/24'), end_address=IPNetwork('192.168.0.10/24'), size=10 + ), + # Partial overlap + IPRange( + start_address=IPNetwork('192.168.0.11/24'), end_address=IPNetwork('192.168.0.17/24'), size=7 + ), + # Full overlap + IPRange( + start_address=IPNetwork('192.168.0.18/24'), end_address=IPNetwork('192.168.0.23/24'), size=6 + ), + # Full overlap + IPRange( + start_address=IPNetwork('192.168.0.24/24'), end_address=IPNetwork('192.168.0.30/24'), size=7 + ), + # Partial overlap + IPRange( + start_address=IPNetwork('192.168.0.31/24'), end_address=IPNetwork('192.168.0.40/24'), size=10 + ), + ) + ) child_ranges = prefix.get_child_ranges() diff --git a/netbox/ipam/tests/test_ordering.py b/netbox/ipam/tests/test_ordering.py index fea6b55e2..2f7a5342d 100644 --- a/netbox/ipam/tests/test_ordering.py +++ b/netbox/ipam/tests/test_ordering.py @@ -92,8 +92,8 @@ class PrefixOrderingTestCase(OrderingTestBase): def test_prefix_complex_ordering(self): """ - This function tests a complex ordering of interwoven prefixes and vrfs. This is the current expected ordering of VRFs - This includes the testing of the Container status. + This function tests a complex ordering of interwoven prefixes and vrfs. This is the current expected ordering + of VRFs. This includes the testing of the Container status. The proper ordering, to get proper containerization should be: None:10.0.0.0/8 @@ -125,7 +125,6 @@ class PrefixOrderingTestCase(OrderingTestBase): class IPAddressOrderingTestCase(OrderingTestBase): - def test_address_vrf_ordering(self): """ This function tests ordering with the inclusion of vrfs @@ -147,24 +146,54 @@ class IPAddressOrderingTestCase(OrderingTestBase): IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf1, address=netaddr.IPNetwork('10.2.2.1/24')), IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf1, address=netaddr.IPNetwork('10.2.3.1/24')), IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf1, address=netaddr.IPNetwork('10.2.4.1/24')), - - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf2, address=netaddr.IPNetwork('172.16.0.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf2, address=netaddr.IPNetwork('172.16.1.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf2, address=netaddr.IPNetwork('172.16.2.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf2, address=netaddr.IPNetwork('172.16.3.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf2, address=netaddr.IPNetwork('172.16.4.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf2, address=netaddr.IPNetwork('172.17.0.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf2, address=netaddr.IPNetwork('172.17.1.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf2, address=netaddr.IPNetwork('172.17.2.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf2, address=netaddr.IPNetwork('172.17.3.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf2, address=netaddr.IPNetwork('172.17.4.1/24')), - - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.0.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.1.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.2.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.3.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.4.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.5.1/24')), + IPAddress( + status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf2, address=netaddr.IPNetwork('172.16.0.1/24') + ), + IPAddress( + status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf2, address=netaddr.IPNetwork('172.16.1.1/24') + ), + IPAddress( + status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf2, address=netaddr.IPNetwork('172.16.2.1/24') + ), + IPAddress( + status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf2, address=netaddr.IPNetwork('172.16.3.1/24') + ), + IPAddress( + status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf2, address=netaddr.IPNetwork('172.16.4.1/24') + ), + IPAddress( + status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf2, address=netaddr.IPNetwork('172.17.0.1/24') + ), + IPAddress( + status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf2, address=netaddr.IPNetwork('172.17.1.1/24') + ), + IPAddress( + status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf2, address=netaddr.IPNetwork('172.17.2.1/24') + ), + IPAddress( + status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf2, address=netaddr.IPNetwork('172.17.3.1/24') + ), + IPAddress( + status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrf2, address=netaddr.IPNetwork('172.17.4.1/24') + ), + IPAddress( + status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.0.1/24') + ), + IPAddress( + status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.1.1/24') + ), + IPAddress( + status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.2.1/24') + ), + IPAddress( + status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.3.1/24') + ), + IPAddress( + status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.4.1/24') + ), + IPAddress( + status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.5.1/24') + ), ) IPAddress.objects.bulk_create(addresses) diff --git a/netbox/ipam/tests/test_views.py b/netbox/ipam/tests/test_views.py index c45777f08..d26a82414 100644 --- a/netbox/ipam/tests/test_views.py +++ b/netbox/ipam/tests/test_views.py @@ -707,11 +707,23 @@ class FHRPGroupTestCase(ViewTestCases.PrimaryObjectViewTestCase): @classmethod def setUpTestData(cls): - fhrp_groups = ( - FHRPGroup(protocol=FHRPGroupProtocolChoices.PROTOCOL_VRRP2, group_id=10, auth_type=FHRPGroupAuthTypeChoices.AUTHENTICATION_PLAINTEXT, auth_key='foobar123'), - FHRPGroup(protocol=FHRPGroupProtocolChoices.PROTOCOL_VRRP3, group_id=20, auth_type=FHRPGroupAuthTypeChoices.AUTHENTICATION_MD5, auth_key='foobar123'), - FHRPGroup(protocol=FHRPGroupProtocolChoices.PROTOCOL_HSRP, group_id=30), + FHRPGroup( + protocol=FHRPGroupProtocolChoices.PROTOCOL_VRRP2, + group_id=10, + auth_type=FHRPGroupAuthTypeChoices.AUTHENTICATION_PLAINTEXT, + auth_key='foobar123', + ), + FHRPGroup( + protocol=FHRPGroupProtocolChoices.PROTOCOL_VRRP3, + group_id=20, + auth_type=FHRPGroupAuthTypeChoices.AUTHENTICATION_MD5, + auth_key='foobar123', + ), + FHRPGroup( + protocol=FHRPGroupProtocolChoices.PROTOCOL_HSRP, + group_id=30 + ), ) FHRPGroup.objects.bulk_create(fhrp_groups) diff --git a/netbox/netbox/filtersets.py b/netbox/netbox/filtersets.py index 657f2f71a..b8fbe7ad5 100644 --- a/netbox/netbox/filtersets.py +++ b/netbox/netbox/filtersets.py @@ -264,7 +264,9 @@ class ChangeLoggedModelFilterSet(BaseFilterSet): action = { 'created_by_request': Q(action=ObjectChangeActionChoices.ACTION_CREATE), 'updated_by_request': Q(action=ObjectChangeActionChoices.ACTION_UPDATE), - 'modified_by_request': Q(action__in=[ObjectChangeActionChoices.ACTION_CREATE, ObjectChangeActionChoices.ACTION_UPDATE]), + 'modified_by_request': Q( + action__in=[ObjectChangeActionChoices.ACTION_CREATE, ObjectChangeActionChoices.ACTION_UPDATE] + ), }.get(name) request_id = value pks = ObjectChange.objects.filter( diff --git a/netbox/netbox/tables/columns.py b/netbox/netbox/tables/columns.py index ee1420396..cf6e1f133 100644 --- a/netbox/netbox/tables/columns.py +++ b/netbox/netbox/tables/columns.py @@ -286,7 +286,8 @@ class ActionsColumn(tables.Column): if len(self.actions) == 1 or (self.split_actions and idx == 0): dropdown_class = attrs.css_class button = ( - f'' + f'' f'' ) @@ -303,7 +304,8 @@ class ActionsColumn(tables.Column): html += ( f'' f' {button}' - f' ' + f' ' f' {toggle_text}' f' ' f'' diff --git a/netbox/netbox/views/generic/bulk_views.py b/netbox/netbox/views/generic/bulk_views.py index 7158f056a..456dd67d2 100644 --- a/netbox/netbox/views/generic/bulk_views.py +++ b/netbox/netbox/views/generic/bulk_views.py @@ -995,7 +995,8 @@ class BulkComponentCreateView(GetReturnURLMixin, BaseMultiObjectView): form.add_error(field, '{}: {}'.format(obj, ', '.join(e))) # Enforce object-level permissions - if self.queryset.filter(pk__in=[obj.pk for obj in new_components]).count() != len(new_components): + component_ids = [obj.pk for obj in new_components] + if self.queryset.filter(pk__in=component_ids).count() != len(new_components): raise PermissionsViolation except IntegrityError: diff --git a/netbox/netbox/views/generic/feature_views.py b/netbox/netbox/views/generic/feature_views.py index 49862e83f..1e17d5354 100644 --- a/netbox/netbox/views/generic/feature_views.py +++ b/netbox/netbox/views/generic/feature_views.py @@ -143,7 +143,12 @@ class ObjectJobsView(ConditionalLoginRequiredMixin, View): """ Render a list of all Job assigned to an object. For example: - path('data-sources//jobs/', ObjectJobsView.as_view(), name='datasource_jobs', kwargs={'model': DataSource}), + path( + 'data-sources//jobs/', + ObjectJobsView.as_view(), + name='datasource_jobs', + kwargs={'model': DataSource} + ) Attributes: base_template: The name of the template to extend. If not provided, "{app}/{model}.html" will be used. diff --git a/netbox/tenancy/migrations/0001_squashed_0012.py b/netbox/tenancy/migrations/0001_squashed_0012.py index e8a028a92..8f3f74d9f 100644 --- a/netbox/tenancy/migrations/0001_squashed_0012.py +++ b/netbox/tenancy/migrations/0001_squashed_0012.py @@ -6,7 +6,6 @@ import taggit.managers class Migration(migrations.Migration): - initial = True dependencies = [ @@ -43,7 +42,16 @@ class Migration(migrations.Migration): ('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')), + ( + 'parent', + mptt.fields.TreeForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name='children', + to='tenancy.tenantgroup', + ), + ), ], options={ 'ordering': ['name'], @@ -60,7 +68,16 @@ class Migration(migrations.Migration): ('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')), + ( + '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={ diff --git a/netbox/tenancy/migrations/0002_squashed_0011.py b/netbox/tenancy/migrations/0002_squashed_0011.py index 8accd1da9..cfdcb58dd 100644 --- a/netbox/tenancy/migrations/0002_squashed_0011.py +++ b/netbox/tenancy/migrations/0002_squashed_0011.py @@ -7,7 +7,6 @@ import utilities.json class Migration(migrations.Migration): - replaces = [ ('tenancy', '0002_tenant_ordering'), ('tenancy', '0003_contacts'), @@ -18,7 +17,7 @@ class Migration(migrations.Migration): ('tenancy', '0008_unique_constraints'), ('tenancy', '0009_standardize_description_comments'), ('tenancy', '0010_tenant_relax_uniqueness'), - ('tenancy', '0011_contactassignment_tags') + ('tenancy', '0011_contactassignment_tags'), ] dependencies = [ @@ -37,7 +36,10 @@ class Migration(migrations.Migration): fields=[ ('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=utilities.json.CustomFieldJSONEncoder), + ), ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), ('name', models.CharField(max_length=100, unique=True)), ('slug', models.SlugField(max_length=100, unique=True)), @@ -53,7 +55,10 @@ class Migration(migrations.Migration): fields=[ ('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=utilities.json.CustomFieldJSONEncoder), + ), ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), ('name', models.CharField(max_length=100)), ('slug', models.SlugField(max_length=100)), @@ -62,7 +67,16 @@ class Migration(migrations.Migration): ('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')), + ( + '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={ @@ -75,7 +89,10 @@ class Migration(migrations.Migration): fields=[ ('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=utilities.json.CustomFieldJSONEncoder), + ), ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), ('name', models.CharField(max_length=100)), ('title', models.CharField(blank=True, max_length=100)), @@ -83,7 +100,16 @@ class Migration(migrations.Migration): ('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')), + ( + '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')), ('link', models.URLField(blank=True)), ], @@ -125,9 +151,24 @@ class Migration(migrations.Migration): ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), ('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')), + ( + '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'), @@ -140,11 +181,16 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='contactassignment', - constraint=models.UniqueConstraint(fields=('content_type', 'object_id', 'contact', 'role'), name='tenancy_contactassignment_unique_object_contact_role'), + 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'), + constraint=models.UniqueConstraint( + fields=('parent', 'name'), name='tenancy_contactgroup_unique_parent_name' + ), ), migrations.AddField( model_name='contact', @@ -163,19 +209,31 @@ class Migration(migrations.Migration): ), 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.'), + 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'), + 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.'), + 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'), + constraint=models.UniqueConstraint( + condition=models.Q(('group__isnull', True)), fields=('slug',), name='tenancy_tenant_unique_slug' + ), ), migrations.AddField( model_name='contactassignment', diff --git a/netbox/tenancy/migrations/0012_contactassignment_custom_fields.py b/netbox/tenancy/migrations/0012_contactassignment_custom_fields.py index ee6726822..7f681fd91 100644 --- a/netbox/tenancy/migrations/0012_contactassignment_custom_fields.py +++ b/netbox/tenancy/migrations/0012_contactassignment_custom_fields.py @@ -5,7 +5,6 @@ import utilities.json class Migration(migrations.Migration): - dependencies = [ ('tenancy', '0011_contactassignment_tags'), ] diff --git a/netbox/tenancy/migrations/0013_gfk_indexes.py b/netbox/tenancy/migrations/0013_gfk_indexes.py index dd23cefbb..9d58c8932 100644 --- a/netbox/tenancy/migrations/0013_gfk_indexes.py +++ b/netbox/tenancy/migrations/0013_gfk_indexes.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('tenancy', '0012_contactassignment_custom_fields'), ] diff --git a/netbox/tenancy/migrations/0014_contactassignment_ordering.py b/netbox/tenancy/migrations/0014_contactassignment_ordering.py index 66f08aa2a..5e2c39311 100644 --- a/netbox/tenancy/migrations/0014_contactassignment_ordering.py +++ b/netbox/tenancy/migrations/0014_contactassignment_ordering.py @@ -4,7 +4,6 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ ('tenancy', '0013_gfk_indexes'), ] diff --git a/netbox/tenancy/migrations/0015_contactassignment_rename_content_type.py b/netbox/tenancy/migrations/0015_contactassignment_rename_content_type.py index 58b14e10f..f2c1ce190 100644 --- a/netbox/tenancy/migrations/0015_contactassignment_rename_content_type.py +++ b/netbox/tenancy/migrations/0015_contactassignment_rename_content_type.py @@ -2,7 +2,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('contenttypes', '0002_remove_content_type_name'), ('extras', '0111_rename_content_types'), @@ -25,16 +24,13 @@ class Migration(migrations.Migration): ), migrations.AddIndex( model_name='contactassignment', - index=models.Index( - fields=['object_type', 'object_id'], - name='tenancy_con_object__6f20f7_idx' - ), + index=models.Index(fields=['object_type', 'object_id'], name='tenancy_con_object__6f20f7_idx'), ), migrations.AddConstraint( model_name='contactassignment', constraint=models.UniqueConstraint( fields=('object_type', 'object_id', 'contact', 'role'), - name='tenancy_contactassignment_unique_object_contact_role' + name='tenancy_contactassignment_unique_object_contact_role', ), ), ] diff --git a/netbox/tenancy/migrations/0016_charfield_null_choices.py b/netbox/tenancy/migrations/0016_charfield_null_choices.py index 815a1bdf2..9f5016a13 100644 --- a/netbox/tenancy/migrations/0016_charfield_null_choices.py +++ b/netbox/tenancy/migrations/0016_charfield_null_choices.py @@ -11,7 +11,6 @@ def set_null_values(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('tenancy', '0015_contactassignment_rename_content_type'), ] @@ -22,8 +21,5 @@ class Migration(migrations.Migration): name='priority', field=models.CharField(blank=True, max_length=50, null=True), ), - migrations.RunPython( - code=set_null_values, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=set_null_values, reverse_code=migrations.RunPython.noop), ] diff --git a/netbox/tenancy/migrations/0017_natural_ordering.py b/netbox/tenancy/migrations/0017_natural_ordering.py index de1fb49aa..beb98d634 100644 --- a/netbox/tenancy/migrations/0017_natural_ordering.py +++ b/netbox/tenancy/migrations/0017_natural_ordering.py @@ -2,7 +2,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('tenancy', '0016_charfield_null_choices'), ('dcim', '0197_natural_sort_collation'), diff --git a/netbox/tenancy/tables/columns.py b/netbox/tenancy/tables/columns.py index ec73cac4a..005bcf737 100644 --- a/netbox/tenancy/tables/columns.py +++ b/netbox/tenancy/tables/columns.py @@ -2,6 +2,7 @@ from django.utils.translation import gettext_lazy as _ import django_tables2 as tables from netbox.tables import columns +from .template_code import * __all__ = ( 'ContactsColumnMixin', @@ -15,15 +16,7 @@ class TenantColumn(tables.TemplateColumn): """ Include the tenant description. """ - template_code = """ - {% if record.tenant %} - {{ record.tenant }} - {% elif record.vrf.tenant %} - {{ record.vrf.tenant }}* - {% else %} - — - {% endif %} - """ + template_code = TENANT_COLUMN def __init__(self, *args, **kwargs): super().__init__(template_code=self.template_code, *args, **kwargs) @@ -36,15 +29,7 @@ class TenantGroupColumn(tables.TemplateColumn): """ Include the tenant group description. """ - template_code = """ - {% if record.tenant and record.tenant.group %} - {{ record.tenant.group }} - {% elif record.vrf.tenant and record.vrf.tenant.group %} - {{ record.vrf.tenant.group }}* - {% else %} - — - {% endif %} - """ + template_code = TENANT_GROUP_COLUMN def __init__(self, accessor=tables.A('tenant__group'), *args, **kwargs): if 'verbose_name' not in kwargs: diff --git a/netbox/tenancy/tables/template_code.py b/netbox/tenancy/tables/template_code.py new file mode 100644 index 000000000..1d15a8708 --- /dev/null +++ b/netbox/tenancy/tables/template_code.py @@ -0,0 +1,19 @@ +TENANT_COLUMN = """ +{% if record.tenant %} + {{ record.tenant }} +{% elif record.vrf.tenant %} + {{ record.vrf.tenant }}* +{% else %} + — +{% endif %} +""" + +TENANT_GROUP_COLUMN = """ +{% if record.tenant and record.tenant.group %} + {{ record.tenant.group }} +{% elif record.vrf.tenant and record.vrf.tenant.group %} + {{ record.vrf.tenant.group }}* +{% else %} + — +{% endif %} +""" diff --git a/netbox/tenancy/tests/test_api.py b/netbox/tenancy/tests/test_api.py index 5a6fe0453..c32ad3826 100644 --- a/netbox/tenancy/tests/test_api.py +++ b/netbox/tenancy/tests/test_api.py @@ -239,9 +239,24 @@ class ContactAssignmentTest(APIViewTestCases.APIViewTestCase): ContactRole.objects.bulk_create(contact_roles) contact_assignments = ( - ContactAssignment(object=sites[0], contact=contacts[0], role=contact_roles[0], priority=ContactPriorityChoices.PRIORITY_PRIMARY), - ContactAssignment(object=sites[0], contact=contacts[1], role=contact_roles[1], priority=ContactPriorityChoices.PRIORITY_SECONDARY), - ContactAssignment(object=sites[0], contact=contacts[2], role=contact_roles[2], priority=ContactPriorityChoices.PRIORITY_TERTIARY), + ContactAssignment( + object=sites[0], + contact=contacts[0], + role=contact_roles[0], + priority=ContactPriorityChoices.PRIORITY_PRIMARY, + ), + ContactAssignment( + object=sites[0], + contact=contacts[1], + role=contact_roles[1], + priority=ContactPriorityChoices.PRIORITY_SECONDARY, + ), + ContactAssignment( + object=sites[0], + contact=contacts[2], + role=contact_roles[2], + priority=ContactPriorityChoices.PRIORITY_TERTIARY, + ), ) ContactAssignment.objects.bulk_create(contact_assignments) diff --git a/netbox/users/migrations/0001_squashed_0011.py b/netbox/users/migrations/0001_squashed_0011.py index cad84201c..263604d34 100644 --- a/netbox/users/migrations/0001_squashed_0011.py +++ b/netbox/users/migrations/0001_squashed_0011.py @@ -8,7 +8,6 @@ import users.models class Migration(migrations.Migration): - initial = True dependencies = [ @@ -39,15 +38,33 @@ class Migration(migrations.Migration): ('password', models.CharField(max_length=128)), ('last_login', models.DateTimeField(blank=True, null=True)), ('is_superuser', models.BooleanField(default=False)), - ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()])), + ( + 'username', + models.CharField( + error_messages={'unique': 'A user with that username already exists.'}, + max_length=150, + unique=True, + validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], + ), + ), ('first_name', models.CharField(blank=True, max_length=150)), ('last_name', models.CharField(blank=True, max_length=150)), ('email', models.EmailField(blank=True, max_length=254)), ('is_staff', models.BooleanField(default=False)), ('is_active', models.BooleanField(default=True)), ('date_joined', models.DateTimeField(default=django.utils.timezone.now)), - ('groups', models.ManyToManyField(blank=True, related_name='user_set', related_query_name='user', to='auth.group')), - ('user_permissions', models.ManyToManyField(blank=True, related_name='user_set', related_query_name='user', to='auth.permission')), + ( + 'groups', + models.ManyToManyField( + blank=True, related_name='user_set', related_query_name='user', to='auth.group' + ), + ), + ( + 'user_permissions', + models.ManyToManyField( + blank=True, related_name='user_set', related_query_name='user', to='auth.permission' + ), + ), ], options={ 'verbose_name': 'user', @@ -64,7 +81,12 @@ class Migration(migrations.Migration): fields=[ ('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)), + ( + 'user', + models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, related_name='config', to=settings.AUTH_USER_MODEL + ), + ), ], options={ 'verbose_name': 'User Preferences', @@ -78,10 +100,20 @@ class Migration(migrations.Migration): ('id', models.BigAutoField(primary_key=True, serialize=False)), ('created', models.DateTimeField(auto_now_add=True)), ('expires', models.DateTimeField(blank=True, null=True)), - ('key', models.CharField(max_length=40, unique=True, validators=[django.core.validators.MinLengthValidator(40)])), + ( + '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)), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tokens', to=settings.AUTH_USER_MODEL)), + ( + 'user', + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, related_name='tokens', to=settings.AUTH_USER_MODEL + ), + ), ], ), migrations.CreateModel( @@ -91,11 +123,37 @@ class Migration(migrations.Migration): ('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)), + ( + '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')), - ('users', models.ManyToManyField(blank=True, related_name='object_permissions', to=settings.AUTH_USER_MODEL)), + ( + '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', diff --git a/netbox/users/migrations/0002_squashed_0004.py b/netbox/users/migrations/0002_squashed_0004.py index 078721c48..275d7a7a9 100644 --- a/netbox/users/migrations/0002_squashed_0004.py +++ b/netbox/users/migrations/0002_squashed_0004.py @@ -5,11 +5,10 @@ import ipam.fields class Migration(migrations.Migration): - replaces = [ ('users', '0002_standardize_id_fields'), ('users', '0003_token_allowed_ips_last_used'), - ('users', '0004_netboxgroup_netboxuser') + ('users', '0004_netboxgroup_netboxuser'), ] dependencies = [ @@ -36,7 +35,9 @@ class Migration(migrations.Migration): 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), + field=django.contrib.postgres.fields.ArrayField( + base_field=ipam.fields.IPNetworkField(), blank=True, null=True, size=None + ), ), migrations.AddField( model_name='token', @@ -45,8 +46,7 @@ class Migration(migrations.Migration): ), migrations.CreateModel( name='NetBoxGroup', - fields=[ - ], + fields=[], options={ 'verbose_name': 'Group', 'proxy': True, diff --git a/netbox/users/migrations/0005_alter_user_table.py b/netbox/users/migrations/0005_alter_user_table.py index 1163da0ae..2e9f699b3 100644 --- a/netbox/users/migrations/0005_alter_user_table.py +++ b/netbox/users/migrations/0005_alter_user_table.py @@ -19,7 +19,6 @@ def update_content_types(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('users', '0002_squashed_0004'), ('extras', '0113_customfield_rename_object_type'), @@ -33,24 +32,17 @@ class Migration(migrations.Migration): name='user', table=None, ), - # Convert the `id` column to a 64-bit integer (BigAutoField is implied by DEFAULT_AUTO_FIELD) - migrations.RunSQL("ALTER TABLE users_user ALTER COLUMN id TYPE bigint"), - + migrations.RunSQL('ALTER TABLE users_user ALTER COLUMN id TYPE bigint'), # Rename auth_user_* sequences - migrations.RunSQL("ALTER TABLE auth_user_groups_id_seq RENAME TO users_user_groups_id_seq"), - migrations.RunSQL("ALTER TABLE auth_user_id_seq RENAME TO users_user_id_seq"), - migrations.RunSQL("ALTER TABLE auth_user_user_permissions_id_seq RENAME TO users_user_user_permissions_id_seq"), - + migrations.RunSQL('ALTER TABLE auth_user_groups_id_seq RENAME TO users_user_groups_id_seq'), + migrations.RunSQL('ALTER TABLE auth_user_id_seq RENAME TO users_user_id_seq'), + migrations.RunSQL('ALTER TABLE auth_user_user_permissions_id_seq RENAME TO users_user_user_permissions_id_seq'), # Rename auth_user_* indexes - migrations.RunSQL("ALTER INDEX auth_user_pkey RENAME TO users_user_pkey"), + migrations.RunSQL('ALTER INDEX auth_user_pkey RENAME TO users_user_pkey'), # Hash is deterministic; generated via schema_editor._create_index_name() - migrations.RunSQL("ALTER INDEX auth_user_username_6821ab7c_like RENAME TO users_user_username_06e46fe6_like"), - migrations.RunSQL("ALTER INDEX auth_user_username_key RENAME TO users_user_username_key"), - + migrations.RunSQL('ALTER INDEX auth_user_username_6821ab7c_like RENAME TO users_user_username_06e46fe6_like'), + migrations.RunSQL('ALTER INDEX auth_user_username_key RENAME TO users_user_username_key'), # Update ContentTypes - migrations.RunPython( - code=update_content_types, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=update_content_types, reverse_code=migrations.RunPython.noop), ] diff --git a/netbox/users/migrations/0006_custom_group_model.py b/netbox/users/migrations/0006_custom_group_model.py index f958d242a..f70c1d58d 100644 --- a/netbox/users/migrations/0006_custom_group_model.py +++ b/netbox/users/migrations/0006_custom_group_model.py @@ -16,7 +16,6 @@ def update_custom_fields(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('users', '0005_alter_user_table'), ] @@ -29,7 +28,12 @@ class Migration(migrations.Migration): ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), ('name', models.CharField(max_length=150, unique=True)), ('description', models.CharField(blank=True, max_length=200)), - ('permissions', models.ManyToManyField(blank=True, related_name='groups', related_query_name='group', to='auth.permission')), + ( + 'permissions', + models.ManyToManyField( + blank=True, related_name='groups', related_query_name='group', to='auth.permission' + ), + ), ], options={ 'ordering': ('name',), @@ -40,17 +44,10 @@ class Migration(migrations.Migration): ('objects', users.models.GroupManager()), ], ), - # Copy existing groups from the old table into the new one - migrations.RunSQL( - "INSERT INTO users_group (SELECT id, name, '' AS description FROM auth_group)" - ), - + migrations.RunSQL("INSERT INTO users_group (SELECT id, name, '' AS description FROM auth_group)"), # Update the sequence for group ID values - migrations.RunSQL( - "SELECT setval('users_group_id_seq', (SELECT MAX(id) FROM users_group))" - ), - + migrations.RunSQL("SELECT setval('users_group_id_seq', (SELECT MAX(id) FROM users_group))"), # Update the "groups" M2M fields on User & ObjectPermission migrations.AlterField( model_name='user', @@ -62,23 +59,12 @@ class Migration(migrations.Migration): name='groups', field=models.ManyToManyField(blank=True, related_name='object_permissions', to='users.group'), ), - # Delete any lingering group assignments for legacy permissions (from before NetBox v2.9) - migrations.RunSQL( - "DELETE from auth_group_permissions" - ), - + migrations.RunSQL('DELETE from auth_group_permissions'), # Delete groups from the old table - migrations.RunSQL( - "DELETE from auth_group" - ), - + migrations.RunSQL('DELETE from auth_group'), # Update custom fields - migrations.RunPython( - code=update_custom_fields, - reverse_code=migrations.RunPython.noop - ), - + migrations.RunPython(code=update_custom_fields, reverse_code=migrations.RunPython.noop), # Delete the proxy model migrations.DeleteModel( name='NetBoxGroup', diff --git a/netbox/users/migrations/0007_objectpermission_update_object_types.py b/netbox/users/migrations/0007_objectpermission_update_object_types.py index d3018a602..598b00b92 100644 --- a/netbox/users/migrations/0007_objectpermission_update_object_types.py +++ b/netbox/users/migrations/0007_objectpermission_update_object_types.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('core', '0010_gfk_indexes'), ('users', '0006_custom_group_model'), @@ -14,6 +13,23 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='objectpermission', name='object_types', - field=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='core.objecttype'), + field=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='core.objecttype', + ), ), ] diff --git a/netbox/users/migrations/0008_flip_objectpermission_assignments.py b/netbox/users/migrations/0008_flip_objectpermission_assignments.py index c61c8b124..11dea5819 100644 --- a/netbox/users/migrations/0008_flip_objectpermission_assignments.py +++ b/netbox/users/migrations/0008_flip_objectpermission_assignments.py @@ -2,7 +2,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('users', '0007_objectpermission_update_object_types'), ] @@ -24,52 +23,47 @@ class Migration(migrations.Migration): database_operations=[ # Rename table migrations.RunSQL( - "ALTER TABLE users_objectpermission_groups" - " RENAME TO users_group_object_permissions" + 'ALTER TABLE users_objectpermission_groups' ' RENAME TO users_group_object_permissions' ), migrations.RunSQL( - "ALTER TABLE users_objectpermission_groups_id_seq" - " RENAME TO users_group_object_permissions_id_seq" + 'ALTER TABLE users_objectpermission_groups_id_seq' + ' RENAME TO users_group_object_permissions_id_seq' ), - # Rename constraints migrations.RunSQL( - "ALTER TABLE users_group_object_permissions RENAME CONSTRAINT " - "users_objectpermissi_group_id_fb7ba6e0_fk_users_gro TO " - "users_group_object_p_group_id_90dd183a_fk_users_gro" + 'ALTER TABLE users_group_object_permissions RENAME CONSTRAINT ' + 'users_objectpermissi_group_id_fb7ba6e0_fk_users_gro TO ' + 'users_group_object_p_group_id_90dd183a_fk_users_gro' ), # Fix for #15698: Drop & recreate constraint which may not exist migrations.RunSQL( - "ALTER TABLE users_group_object_permissions DROP CONSTRAINT IF EXISTS " - "users_objectpermissi_objectpermission_id_2f7cc117_fk_users_obj" + 'ALTER TABLE users_group_object_permissions DROP CONSTRAINT IF EXISTS ' + 'users_objectpermissi_objectpermission_id_2f7cc117_fk_users_obj' ), migrations.RunSQL( - "ALTER TABLE users_group_object_permissions ADD CONSTRAINT " - "users_group_object_p_objectpermission_id_dd489dc4_fk_users_obj " - "FOREIGN KEY (objectpermission_id) REFERENCES users_objectpermission(id) " - "DEFERRABLE INITIALLY DEFERRED" + 'ALTER TABLE users_group_object_permissions ADD CONSTRAINT ' + 'users_group_object_p_objectpermission_id_dd489dc4_fk_users_obj ' + 'FOREIGN KEY (objectpermission_id) REFERENCES users_objectpermission(id) ' + 'DEFERRABLE INITIALLY DEFERRED' ), - # Rename indexes migrations.RunSQL( - "ALTER INDEX users_objectpermission_groups_pkey " - " RENAME TO users_group_object_permissions_pkey" + 'ALTER INDEX users_objectpermission_groups_pkey ' ' RENAME TO users_group_object_permissions_pkey' ), migrations.RunSQL( - "ALTER INDEX users_objectpermission_g_objectpermission_id_grou_3b62a39c_uniq " - " RENAME TO users_group_object_permi_group_id_objectpermissio_db1f8cbe_uniq" + 'ALTER INDEX users_objectpermission_g_objectpermission_id_grou_3b62a39c_uniq ' + ' RENAME TO users_group_object_permi_group_id_objectpermissio_db1f8cbe_uniq' ), migrations.RunSQL( - "ALTER INDEX users_objectpermission_groups_group_id_fb7ba6e0" - " RENAME TO users_group_object_permissions_group_id_90dd183a" + 'ALTER INDEX users_objectpermission_groups_group_id_fb7ba6e0' + ' RENAME TO users_group_object_permissions_group_id_90dd183a' ), migrations.RunSQL( - "ALTER INDEX users_objectpermission_groups_objectpermission_id_2f7cc117" - " RENAME TO users_group_object_permissions_objectpermission_id_dd489dc4" + 'ALTER INDEX users_objectpermission_groups_objectpermission_id_2f7cc117' + ' RENAME TO users_group_object_permissions_objectpermission_id_dd489dc4' ), - ] + ], ), - # Flip M2M assignments for ObjectPermission to Users migrations.SeparateDatabaseAndState( state_operations=[ @@ -86,49 +80,44 @@ class Migration(migrations.Migration): database_operations=[ # Rename table migrations.RunSQL( - "ALTER TABLE users_objectpermission_users" - " RENAME TO users_user_object_permissions" + 'ALTER TABLE users_objectpermission_users' ' RENAME TO users_user_object_permissions' ), migrations.RunSQL( - "ALTER TABLE users_objectpermission_users_id_seq" - " RENAME TO users_user_object_permissions_id_seq" + 'ALTER TABLE users_objectpermission_users_id_seq' ' RENAME TO users_user_object_permissions_id_seq' ), - # Rename constraints migrations.RunSQL( - "ALTER TABLE users_user_object_permissions RENAME CONSTRAINT " - "users_objectpermission_users_user_id_16c0905d_fk_auth_user_id TO " - "users_user_object_permissions_user_id_9d647aac_fk_users_user_id" + 'ALTER TABLE users_user_object_permissions RENAME CONSTRAINT ' + 'users_objectpermission_users_user_id_16c0905d_fk_auth_user_id TO ' + 'users_user_object_permissions_user_id_9d647aac_fk_users_user_id' ), # Fix for #15698: Drop & recreate constraint which may not exist migrations.RunSQL( - "ALTER TABLE users_user_object_permissions DROP CONSTRAINT IF EXISTS " - "users_objectpermissi_objectpermission_id_78a9c2e6_fk_users_obj" + 'ALTER TABLE users_user_object_permissions DROP CONSTRAINT IF EXISTS ' + 'users_objectpermissi_objectpermission_id_78a9c2e6_fk_users_obj' ), migrations.RunSQL( - "ALTER TABLE users_user_object_permissions ADD CONSTRAINT " - "users_user_object_pe_objectpermission_id_29b431b4_fk_users_obj " - "FOREIGN KEY (objectpermission_id) REFERENCES users_objectpermission(id) " - "DEFERRABLE INITIALLY DEFERRED" + 'ALTER TABLE users_user_object_permissions ADD CONSTRAINT ' + 'users_user_object_pe_objectpermission_id_29b431b4_fk_users_obj ' + 'FOREIGN KEY (objectpermission_id) REFERENCES users_objectpermission(id) ' + 'DEFERRABLE INITIALLY DEFERRED' ), - # Rename indexes migrations.RunSQL( - "ALTER INDEX users_objectpermission_users_pkey " - " RENAME TO users_user_object_permissions_pkey" + 'ALTER INDEX users_objectpermission_users_pkey ' ' RENAME TO users_user_object_permissions_pkey' ), migrations.RunSQL( - "ALTER INDEX users_objectpermission_u_objectpermission_id_user_3a7db108_uniq " - " RENAME TO users_user_object_permis_user_id_objectpermission_0a98550e_uniq" + 'ALTER INDEX users_objectpermission_u_objectpermission_id_user_3a7db108_uniq ' + ' RENAME TO users_user_object_permis_user_id_objectpermission_0a98550e_uniq' ), migrations.RunSQL( - "ALTER INDEX users_objectpermission_users_user_id_16c0905d" - " RENAME TO users_user_object_permissions_user_id_9d647aac" + 'ALTER INDEX users_objectpermission_users_user_id_16c0905d' + ' RENAME TO users_user_object_permissions_user_id_9d647aac' ), migrations.RunSQL( - "ALTER INDEX users_objectpermission_users_objectpermission_id_78a9c2e6" - " RENAME TO users_user_object_permissions_objectpermission_id_29b431b4" + 'ALTER INDEX users_objectpermission_users_objectpermission_id_78a9c2e6' + ' RENAME TO users_user_object_permissions_objectpermission_id_29b431b4' ), - ] + ], ), ] diff --git a/netbox/users/migrations/0009_update_group_perms.py b/netbox/users/migrations/0009_update_group_perms.py index f3b197492..7698fd1e7 100644 --- a/netbox/users/migrations/0009_update_group_perms.py +++ b/netbox/users/migrations/0009_update_group_perms.py @@ -18,17 +18,13 @@ def update_content_types(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('users', '0008_flip_objectpermission_assignments'), ] operations = [ # Update ContentTypes - migrations.RunPython( - code=update_content_types, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=update_content_types, reverse_code=migrations.RunPython.noop), migrations.AlterField( model_name='objectpermission', name='object_types', diff --git a/netbox/users/tests/test_filtersets.py b/netbox/users/tests/test_filtersets.py index fdf25d970..8b683b346 100644 --- a/netbox/users/tests/test_filtersets.py +++ b/netbox/users/tests/test_filtersets.py @@ -286,9 +286,15 @@ class TokenTestCase(TestCase, BaseFilterSetTests): future_date = make_aware(datetime.datetime(3000, 1, 1)) past_date = make_aware(datetime.datetime(2000, 1, 1)) tokens = ( - Token(user=users[0], key=Token.generate_key(), expires=future_date, write_enabled=True, description='foobar1'), - Token(user=users[1], key=Token.generate_key(), expires=future_date, write_enabled=True, description='foobar2'), - Token(user=users[2], key=Token.generate_key(), expires=past_date, write_enabled=False), + Token( + user=users[0], key=Token.generate_key(), expires=future_date, write_enabled=True, description='foobar1' + ), + Token( + user=users[1], key=Token.generate_key(), expires=future_date, write_enabled=True, description='foobar2' + ), + Token( + user=users[2], key=Token.generate_key(), expires=past_date, write_enabled=False + ), ) Token.objects.bulk_create(tokens) diff --git a/netbox/users/tests/test_views.py b/netbox/users/tests/test_views.py index 8386364dd..8226a8be9 100644 --- a/netbox/users/tests/test_views.py +++ b/netbox/users/tests/test_views.py @@ -23,11 +23,16 @@ class UserTestCase( @classmethod def setUpTestData(cls): - users = ( - User(username='username1', first_name='first1', last_name='last1', email='user1@foo.com', password='pass1xxx'), - User(username='username2', first_name='first2', last_name='last2', email='user2@foo.com', password='pass2xxx'), - User(username='username3', first_name='first3', last_name='last3', email='user3@foo.com', password='pass3xxx'), + User( + username='username1', first_name='first1', last_name='last1', email='user1@foo.com', password='pass1xxx' + ), + User( + username='username2', first_name='first2', last_name='last2', email='user2@foo.com', password='pass2xxx' + ), + User( + username='username3', first_name='first3', last_name='last3', email='user3@foo.com', password='pass3xxx' + ), ) User.objects.bulk_create(users) diff --git a/netbox/utilities/socks.py b/netbox/utilities/socks.py index bb0b6b250..6b62e8fc7 100644 --- a/netbox/utilities/socks.py +++ b/netbox/utilities/socks.py @@ -26,7 +26,10 @@ class ProxyHTTPConnection(HTTPConnection): try: from python_socks.sync import Proxy except ModuleNotFoundError as e: - logger.info("Configuring an HTTP proxy using SOCKS requires the python_socks library. Check that it has been installed.") + logger.info( + "Configuring an HTTP proxy using SOCKS requires the python_socks library. Check that it has been " + "installed." + ) raise e proxy = Proxy.from_url(self._proxy_url, rdns=self.use_rdns) diff --git a/netbox/utilities/testing/api.py b/netbox/utilities/testing/api.py index 0471b1cfd..12e38a27f 100644 --- a/netbox/utilities/testing/api.py +++ b/netbox/utilities/testing/api.py @@ -443,7 +443,10 @@ class APIViewTestCases: # Compile list of fields to include fields_string = '' - file_fields = (strawberry_django.fields.types.DjangoFileType, strawberry_django.fields.types.DjangoImageType) + file_fields = ( + strawberry_django.fields.types.DjangoFileType, + strawberry_django.fields.types.DjangoImageType, + ) for field in type_class.__strawberry_definition__.fields: if ( field.type in file_fields or ( diff --git a/netbox/utilities/tests/test_filters.py b/netbox/utilities/tests/test_filters.py index 031f31a12..6956396d2 100644 --- a/netbox/utilities/tests/test_filters.py +++ b/netbox/utilities/tests/test_filters.py @@ -427,9 +427,46 @@ class DynamicFilterLookupExpressionTest(TestCase): Rack.objects.bulk_create(racks) devices = ( - Device(name='Device 1', device_type=device_types[0], role=roles[0], platform=platforms[0], serial='ABC', asset_tag='1001', site=sites[0], rack=racks[0], position=1, face=DeviceFaceChoices.FACE_FRONT, status=DeviceStatusChoices.STATUS_ACTIVE, local_context_data={"foo": 123}), - Device(name='Device 2', device_type=device_types[1], role=roles[1], platform=platforms[1], serial='DEF', asset_tag='1002', site=sites[1], rack=racks[1], position=2, face=DeviceFaceChoices.FACE_FRONT, status=DeviceStatusChoices.STATUS_STAGED), - Device(name='Device 3', device_type=device_types[2], role=roles[2], platform=platforms[2], serial='GHI', asset_tag='1003', site=sites[2], rack=racks[2], position=3, face=DeviceFaceChoices.FACE_REAR, status=DeviceStatusChoices.STATUS_FAILED), + Device( + name='Device 1', + device_type=device_types[0], + role=roles[0], + platform=platforms[0], + serial='ABC', + asset_tag='1001', + site=sites[0], + rack=racks[0], + position=1, + face=DeviceFaceChoices.FACE_FRONT, + status=DeviceStatusChoices.STATUS_ACTIVE, + local_context_data={'foo': 123}, + ), + Device( + name='Device 2', + device_type=device_types[1], + role=roles[1], + platform=platforms[1], + serial='DEF', + asset_tag='1002', + site=sites[1], + rack=racks[1], + position=2, + face=DeviceFaceChoices.FACE_FRONT, + status=DeviceStatusChoices.STATUS_STAGED, + ), + Device( + name='Device 3', + device_type=device_types[2], + role=roles[2], + platform=platforms[2], + serial='GHI', + asset_tag='1003', + site=sites[2], + rack=racks[2], + position=3, + face=DeviceFaceChoices.FACE_REAR, + status=DeviceStatusChoices.STATUS_FAILED, + ), ) Device.objects.bulk_create(devices) diff --git a/netbox/virtualization/api/serializers_/clusters.py b/netbox/virtualization/api/serializers_/clusters.py index 450924fef..ff64db1cf 100644 --- a/netbox/virtualization/api/serializers_/clusters.py +++ b/netbox/virtualization/api/serializers_/clusters.py @@ -75,9 +75,9 @@ class ClusterSerializer(NetBoxModelSerializer): class Meta: model = Cluster fields = [ - 'id', 'url', 'display_url', 'display', 'name', 'type', 'group', 'status', 'tenant', 'scope_type', 'scope_id', 'scope', - 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'device_count', - 'virtualmachine_count', 'allocated_vcpus', 'allocated_memory', 'allocated_disk' + 'id', 'url', 'display_url', 'display', 'name', 'type', 'group', 'status', 'tenant', 'scope_type', + 'scope_id', 'scope', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', + 'device_count', 'virtualmachine_count', 'allocated_vcpus', 'allocated_memory', 'allocated_disk' ] brief_fields = ('id', 'url', 'display', 'name', 'description', 'virtualmachine_count') diff --git a/netbox/virtualization/api/serializers_/virtualmachines.py b/netbox/virtualization/api/serializers_/virtualmachines.py index dfc205b7c..05fa2e427 100644 --- a/netbox/virtualization/api/serializers_/virtualmachines.py +++ b/netbox/virtualization/api/serializers_/virtualmachines.py @@ -49,8 +49,8 @@ class VirtualMachineSerializer(NetBoxModelSerializer): class Meta: model = VirtualMachine fields = [ - 'id', 'url', 'display_url', 'display', 'name', 'status', 'site', 'cluster', 'device', 'serial', 'role', 'tenant', - 'platform', 'primary_ip', 'primary_ip4', 'primary_ip6', 'vcpus', 'memory', 'disk', 'description', + 'id', 'url', 'display_url', 'display', 'name', 'status', 'site', 'cluster', 'device', 'serial', 'role', + 'tenant', 'platform', 'primary_ip', 'primary_ip4', 'primary_ip6', 'vcpus', 'memory', 'disk', 'description', 'comments', 'config_template', 'local_context_data', 'tags', 'custom_fields', 'created', 'last_updated', 'interface_count', 'virtual_disk_count', ] @@ -62,8 +62,8 @@ class VirtualMachineWithConfigContextSerializer(VirtualMachineSerializer): class Meta(VirtualMachineSerializer.Meta): fields = [ - 'id', 'url', 'display_url', 'display', 'name', 'status', 'site', 'cluster', 'device', 'serial', 'role', 'tenant', - 'platform', 'primary_ip', 'primary_ip4', 'primary_ip6', 'vcpus', 'memory', 'disk', 'description', + 'id', 'url', 'display_url', 'display', 'name', 'status', 'site', 'cluster', 'device', 'serial', 'role', + 'tenant', 'platform', 'primary_ip', 'primary_ip4', 'primary_ip6', 'vcpus', 'memory', 'disk', 'description', 'comments', 'config_template', 'local_context_data', 'tags', 'custom_fields', 'config_context', 'created', 'last_updated', 'interface_count', 'virtual_disk_count', ] diff --git a/netbox/virtualization/forms/bulk_import.py b/netbox/virtualization/forms/bulk_import.py index 027f3b309..6b5b62d11 100644 --- a/netbox/virtualization/forms/bulk_import.py +++ b/netbox/virtualization/forms/bulk_import.py @@ -73,7 +73,9 @@ class ClusterImportForm(ScopedImportForm, NetBoxModelImportForm): class Meta: model = Cluster - fields = ('name', 'type', 'group', 'status', 'scope_type', 'scope_id', 'tenant', 'description', 'comments', 'tags') + fields = ( + 'name', 'type', 'group', 'status', 'scope_type', 'scope_id', 'tenant', 'description', 'comments', 'tags', + ) labels = { 'scope_id': _('Scope ID'), } diff --git a/netbox/virtualization/migrations/0001_squashed_0022.py b/netbox/virtualization/migrations/0001_squashed_0022.py index 2a7894737..c7aa35ec7 100644 --- a/netbox/virtualization/migrations/0001_squashed_0022.py +++ b/netbox/virtualization/migrations/0001_squashed_0022.py @@ -10,7 +10,6 @@ import utilities.query_functions class Migration(migrations.Migration): - initial = True dependencies = [ @@ -100,17 +99,79 @@ class Migration(migrations.Migration): ('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)])), + ( + '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')), + ( + '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')), + ( + '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'), @@ -120,12 +181,24 @@ class Migration(migrations.Migration): migrations.AddField( model_name='cluster', name='group', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='clusters', to='virtualization.clustergroup'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='clusters', + to='virtualization.clustergroup', + ), ), migrations.AddField( model_name='cluster', name='site', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='clusters', to='dcim.site'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='clusters', + to='dcim.site', + ), ), migrations.AddField( model_name='cluster', @@ -135,12 +208,20 @@ class Migration(migrations.Migration): migrations.AddField( model_name='cluster', name='tenant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='clusters', to='tenancy.tenant'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='clusters', + to='tenancy.tenant', + ), ), migrations.AddField( model_name='cluster', name='type', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='clusters', to='virtualization.clustertype'), + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, related_name='clusters', to='virtualization.clustertype' + ), ), migrations.CreateModel( name='VMInterface', @@ -151,16 +232,59 @@ class Migration(migrations.Migration): ('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)])), + ( + '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)), + ( + '_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')), + ( + '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')), + ( + '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', diff --git a/netbox/virtualization/migrations/0023_squashed_0036.py b/netbox/virtualization/migrations/0023_squashed_0036.py index bbfb62b39..0665aaab6 100644 --- a/netbox/virtualization/migrations/0023_squashed_0036.py +++ b/netbox/virtualization/migrations/0023_squashed_0036.py @@ -7,7 +7,6 @@ import utilities.ordering class Migration(migrations.Migration): - replaces = [ ('virtualization', '0023_virtualmachine_natural_ordering'), ('virtualization', '0024_cluster_relax_uniqueness'), @@ -22,7 +21,7 @@ class Migration(migrations.Migration): ('virtualization', '0033_unique_constraints'), ('virtualization', '0034_standardize_description_comments'), ('virtualization', '0035_virtualmachine_interface_count'), - ('virtualization', '0036_virtualmachine_config_template') + ('virtualization', '0036_virtualmachine_config_template'), ] dependencies = [ @@ -40,7 +39,9 @@ class Migration(migrations.Migration): migrations.AddField( model_name='virtualmachine', name='_name', - field=utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize), + field=utilities.fields.NaturalOrderingField( + 'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize + ), ), migrations.AlterField( model_name='cluster', @@ -64,7 +65,13 @@ class Migration(migrations.Migration): 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'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name='bridge_interfaces', + to='virtualization.vminterface', + ), ), migrations.AlterField( model_name='cluster', @@ -94,7 +101,13 @@ class Migration(migrations.Migration): 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'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name='vminterfaces', + to='ipam.vrf', + ), ), migrations.AlterField( model_name='cluster', @@ -129,17 +142,35 @@ class Migration(migrations.Migration): 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'), + 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'), + 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'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='virtual_machines', + to='virtualization.cluster', + ), ), migrations.AlterUniqueTogether( name='cluster', @@ -155,7 +186,9 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='cluster', - constraint=models.UniqueConstraint(fields=('group', 'name'), name='virtualization_cluster_unique_group_name'), + constraint=models.UniqueConstraint( + fields=('group', 'name'), name='virtualization_cluster_unique_group_name' + ), ), migrations.AddConstraint( model_name='cluster', @@ -163,15 +196,28 @@ class Migration(migrations.Migration): ), 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'), + 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.'), + 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'), + constraint=models.UniqueConstraint( + fields=('virtual_machine', 'name'), name='virtualization_vminterface_unique_virtual_machine_name' + ), ), migrations.AddField( model_name='cluster', @@ -186,11 +232,19 @@ class Migration(migrations.Migration): migrations.AddField( model_name='virtualmachine', name='interface_count', - field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='virtual_machine', to_model='virtualization.VMInterface'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, to_field='virtual_machine', to_model='virtualization.VMInterface' + ), ), 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'), + 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/virtualization/migrations/0037_protect_child_interfaces.py b/netbox/virtualization/migrations/0037_protect_child_interfaces.py index ab6cf0cb3..a9d2075c1 100644 --- a/netbox/virtualization/migrations/0037_protect_child_interfaces.py +++ b/netbox/virtualization/migrations/0037_protect_child_interfaces.py @@ -5,7 +5,6 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ ('virtualization', '0036_virtualmachine_config_template'), ] @@ -14,6 +13,12 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='vminterface', name='parent', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.RESTRICT, related_name='child_interfaces', to='virtualization.vminterface'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.RESTRICT, + related_name='child_interfaces', + to='virtualization.vminterface', + ), ), ] diff --git a/netbox/virtualization/migrations/0038_virtualdisk.py b/netbox/virtualization/migrations/0038_virtualdisk.py index 59d45c975..2f7824121 100644 --- a/netbox/virtualization/migrations/0038_virtualdisk.py +++ b/netbox/virtualization/migrations/0038_virtualdisk.py @@ -9,7 +9,6 @@ import utilities.tracking class Migration(migrations.Migration): - dependencies = [ ('extras', '0099_cachedvalue_ordering'), ('virtualization', '0037_protect_child_interfaces'), @@ -19,7 +18,9 @@ class Migration(migrations.Migration): migrations.AddField( model_name='virtualmachine', name='virtual_disk_count', - field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='virtual_machine', to_model='virtualization.VirtualDisk'), + field=utilities.fields.CounterCacheField( + default=0, editable=False, to_field='virtual_machine', to_model='virtualization.VirtualDisk' + ), ), migrations.CreateModel( name='VirtualDisk', @@ -27,13 +28,28 @@ class Migration(migrations.Migration): ('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=utilities.json.CustomFieldJSONEncoder), + ), ('name', models.CharField(max_length=64)), - ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize_interface)), + ( + '_name', + utilities.fields.NaturalOrderingField( + 'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize_interface + ), + ), ('description', models.CharField(blank=True, max_length=200)), ('size', models.PositiveIntegerField()), ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), - ('virtual_machine', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='virtualization.virtualmachine')), + ( + 'virtual_machine', + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name='%(class)ss', + to='virtualization.virtualmachine', + ), + ), ], options={ 'verbose_name': 'virtual disk', @@ -45,6 +61,8 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='virtualdisk', - constraint=models.UniqueConstraint(fields=('virtual_machine', 'name'), name='virtualization_virtualdisk_unique_virtual_machine_name'), + constraint=models.UniqueConstraint( + fields=('virtual_machine', 'name'), name='virtualization_virtualdisk_unique_virtual_machine_name' + ), ), ] diff --git a/netbox/virtualization/migrations/0039_virtualmachine_serial_number.py b/netbox/virtualization/migrations/0039_virtualmachine_serial_number.py index 15b58fa22..758c21edc 100644 --- a/netbox/virtualization/migrations/0039_virtualmachine_serial_number.py +++ b/netbox/virtualization/migrations/0039_virtualmachine_serial_number.py @@ -2,7 +2,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('virtualization', '0038_virtualdisk'), ] diff --git a/netbox/virtualization/migrations/0040_convert_disk_size.py b/netbox/virtualization/migrations/0040_convert_disk_size.py index 6471a0908..4b0aec7bd 100644 --- a/netbox/virtualization/migrations/0040_convert_disk_size.py +++ b/netbox/virtualization/migrations/0040_convert_disk_size.py @@ -18,14 +18,10 @@ def convert_disk_size(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('virtualization', '0039_virtualmachine_serial_number'), ] operations = [ - migrations.RunPython( - code=convert_disk_size, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=convert_disk_size, reverse_code=migrations.RunPython.noop), ] diff --git a/netbox/virtualization/migrations/0041_charfield_null_choices.py b/netbox/virtualization/migrations/0041_charfield_null_choices.py index 88b7f9b2c..22eb9955a 100644 --- a/netbox/virtualization/migrations/0041_charfield_null_choices.py +++ b/netbox/virtualization/migrations/0041_charfield_null_choices.py @@ -11,7 +11,6 @@ def set_null_values(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('virtualization', '0040_convert_disk_size'), ] @@ -22,8 +21,5 @@ class Migration(migrations.Migration): name='mode', field=models.CharField(blank=True, max_length=50, null=True), ), - migrations.RunPython( - code=set_null_values, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=set_null_values, reverse_code=migrations.RunPython.noop), ] diff --git a/netbox/virtualization/migrations/0042_vminterface_vlan_translation_policy.py b/netbox/virtualization/migrations/0042_vminterface_vlan_translation_policy.py index 3a6d5e481..ad93a751f 100644 --- a/netbox/virtualization/migrations/0042_vminterface_vlan_translation_policy.py +++ b/netbox/virtualization/migrations/0042_vminterface_vlan_translation_policy.py @@ -3,7 +3,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('ipam', '0074_vlantranslationpolicy_vlantranslationrule'), ('virtualization', '0041_charfield_null_choices'), @@ -13,6 +12,8 @@ class Migration(migrations.Migration): migrations.AddField( model_name='vminterface', name='vlan_translation_policy', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='ipam.vlantranslationpolicy'), + field=models.ForeignKey( + blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='ipam.vlantranslationpolicy' + ), ), ] diff --git a/netbox/virtualization/migrations/0043_qinq_svlan.py b/netbox/virtualization/migrations/0043_qinq_svlan.py index 422289fb7..b407facce 100644 --- a/netbox/virtualization/migrations/0043_qinq_svlan.py +++ b/netbox/virtualization/migrations/0043_qinq_svlan.py @@ -3,7 +3,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('ipam', '0075_vlan_qinq'), ('virtualization', '0042_vminterface_vlan_translation_policy'), @@ -13,7 +12,13 @@ class Migration(migrations.Migration): migrations.AddField( model_name='vminterface', name='qinq_svlan', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(class)ss_svlan', to='ipam.vlan'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name='%(class)ss_svlan', + to='ipam.vlan', + ), ), migrations.AlterField( model_name='vminterface', @@ -23,6 +28,12 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='vminterface', name='untagged_vlan', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(class)ss_as_untagged', to='ipam.vlan'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name='%(class)ss_as_untagged', + to='ipam.vlan', + ), ), ] diff --git a/netbox/virtualization/migrations/0044_cluster_scope.py b/netbox/virtualization/migrations/0044_cluster_scope.py index b7af25f8b..521db1877 100644 --- a/netbox/virtualization/migrations/0044_cluster_scope.py +++ b/netbox/virtualization/migrations/0044_cluster_scope.py @@ -11,13 +11,11 @@ def copy_site_assignments(apps, schema_editor): Site = apps.get_model('dcim', 'Site') Cluster.objects.filter(site__isnull=False).update( - scope_type=ContentType.objects.get_for_model(Site), - scope_id=models.F('site_id') + scope_type=ContentType.objects.get_for_model(Site), scope_id=models.F('site_id') ) class Migration(migrations.Migration): - dependencies = [ ('contenttypes', '0002_remove_content_type_name'), ('virtualization', '0043_qinq_svlan'), @@ -41,11 +39,6 @@ class Migration(migrations.Migration): to='contenttypes.contenttype', ), ), - # Copy over existing site assignments - migrations.RunPython( - code=copy_site_assignments, - reverse_code=migrations.RunPython.noop - ), - + migrations.RunPython(code=copy_site_assignments, reverse_code=migrations.RunPython.noop), ] diff --git a/netbox/virtualization/migrations/0045_clusters_cached_relations.py b/netbox/virtualization/migrations/0045_clusters_cached_relations.py index ff851aa7c..6d0c8ff33 100644 --- a/netbox/virtualization/migrations/0045_clusters_cached_relations.py +++ b/netbox/virtualization/migrations/0045_clusters_cached_relations.py @@ -19,7 +19,6 @@ def populate_denormalized_fields(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('virtualization', '0044_cluster_scope'), ] @@ -69,13 +68,8 @@ class Migration(migrations.Migration): to='dcim.sitegroup', ), ), - # Populate denormalized FK values - migrations.RunPython( - code=populate_denormalized_fields, - reverse_code=migrations.RunPython.noop - ), - + migrations.RunPython(code=populate_denormalized_fields, reverse_code=migrations.RunPython.noop), migrations.RemoveConstraint( model_name='cluster', name='virtualization_cluster_unique_site_name', diff --git a/netbox/virtualization/migrations/0046_alter_cluster__location_alter_cluster__region_and_more.py b/netbox/virtualization/migrations/0046_alter_cluster__location_alter_cluster__region_and_more.py index 7b1168da0..75c806382 100644 --- a/netbox/virtualization/migrations/0046_alter_cluster__location_alter_cluster__region_and_more.py +++ b/netbox/virtualization/migrations/0046_alter_cluster__location_alter_cluster__region_and_more.py @@ -5,7 +5,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('dcim', '0196_qinq_svlan'), ('virtualization', '0045_clusters_cached_relations'), diff --git a/netbox/virtualization/migrations/0047_natural_ordering.py b/netbox/virtualization/migrations/0047_natural_ordering.py index 4454cfe2d..4ce5b8370 100644 --- a/netbox/virtualization/migrations/0047_natural_ordering.py +++ b/netbox/virtualization/migrations/0047_natural_ordering.py @@ -2,7 +2,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('virtualization', '0046_alter_cluster__location_alter_cluster__region_and_more'), ('dcim', '0197_natural_sort_collation'), diff --git a/netbox/virtualization/migrations/0048_populate_mac_addresses.py b/netbox/virtualization/migrations/0048_populate_mac_addresses.py index 328d6438a..a4be1e2be 100644 --- a/netbox/virtualization/migrations/0048_populate_mac_addresses.py +++ b/netbox/virtualization/migrations/0048_populate_mac_addresses.py @@ -10,9 +10,7 @@ def populate_mac_addresses(apps, schema_editor): mac_addresses = [ MACAddress( - mac_address=vminterface.mac_address, - assigned_object_type=vminterface_ct, - assigned_object_id=vminterface.pk + mac_address=vminterface.mac_address, assigned_object_type=vminterface_ct, assigned_object_id=vminterface.pk ) for vminterface in VMInterface.objects.filter(mac_address__isnull=False) ] @@ -24,7 +22,6 @@ def populate_mac_addresses(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('dcim', '0199_macaddress'), ('virtualization', '0047_natural_ordering'), @@ -39,13 +36,10 @@ class Migration(migrations.Migration): null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', - to='dcim.macaddress' + to='dcim.macaddress', ), ), - migrations.RunPython( - code=populate_mac_addresses, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=populate_mac_addresses, reverse_code=migrations.RunPython.noop), migrations.RemoveField( model_name='vminterface', name='mac_address', diff --git a/netbox/virtualization/tables/clusters.py b/netbox/virtualization/tables/clusters.py index 91807e35b..d07bb4519 100644 --- a/netbox/virtualization/tables/clusters.py +++ b/netbox/virtualization/tables/clusters.py @@ -100,7 +100,7 @@ class ClusterTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable): class Meta(NetBoxTable.Meta): model = Cluster fields = ( - 'pk', 'id', 'name', 'type', 'group', 'status', 'tenant', 'tenant_group', 'scope', 'scope_type', 'description', - 'comments', 'device_count', 'vm_count', 'contacts', 'tags', 'created', 'last_updated', + 'pk', 'id', 'name', 'type', 'group', 'status', 'tenant', 'tenant_group', 'scope', 'scope_type', + 'description', 'comments', 'device_count', 'vm_count', 'contacts', 'tags', 'created', 'last_updated', ) default_columns = ('pk', 'name', 'type', 'group', 'status', 'tenant', 'site', 'device_count', 'vm_count') diff --git a/netbox/virtualization/tables/template_code.py b/netbox/virtualization/tables/template_code.py new file mode 100644 index 000000000..a6b7251f2 --- /dev/null +++ b/netbox/virtualization/tables/template_code.py @@ -0,0 +1,32 @@ +VMINTERFACE_BUTTONS = """ +{% if perms.virtualization.change_vminterface %} + + + + +{% endif %} +{% if perms.vpn.add_tunnel and not record.tunnel_termination %} + + + +{% elif perms.vpn.delete_tunneltermination and record.tunnel_termination %} + + + +{% endif %} +""" diff --git a/netbox/virtualization/tables/virtualmachines.py b/netbox/virtualization/tables/virtualmachines.py index fe7a66ac1..116051037 100644 --- a/netbox/virtualization/tables/virtualmachines.py +++ b/netbox/virtualization/tables/virtualmachines.py @@ -6,6 +6,7 @@ from netbox.tables import NetBoxTable, columns from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin from utilities.templatetags.helpers import humanize_megabytes from virtualization.models import VirtualDisk, VirtualMachine, VMInterface +from .template_code import * __all__ = ( 'VirtualDiskTable', @@ -15,39 +16,6 @@ __all__ = ( 'VMInterfaceTable', ) -VMINTERFACE_BUTTONS = """ -{% if perms.virtualization.change_vminterface %} - - - - -{% endif %} -{% if perms.vpn.add_tunnel and not record.tunnel_termination %} - - - -{% elif perms.vpn.delete_tunneltermination and record.tunnel_termination %} - - - -{% endif %} -""" - # # Virtual machines diff --git a/netbox/virtualization/tests/test_api.py b/netbox/virtualization/tests/test_api.py index 149b64684..c57b57f2e 100644 --- a/netbox/virtualization/tests/test_api.py +++ b/netbox/virtualization/tests/test_api.py @@ -109,9 +109,24 @@ class ClusterTest(APIViewTestCases.APIViewTestCase): ClusterGroup.objects.bulk_create(cluster_groups) clusters = ( - Cluster(name='Cluster 1', type=cluster_types[0], group=cluster_groups[0], status=ClusterStatusChoices.STATUS_PLANNED), - Cluster(name='Cluster 2', type=cluster_types[0], group=cluster_groups[0], status=ClusterStatusChoices.STATUS_PLANNED), - Cluster(name='Cluster 3', type=cluster_types[0], group=cluster_groups[0], status=ClusterStatusChoices.STATUS_PLANNED), + Cluster( + name='Cluster 1', + type=cluster_types[0], + group=cluster_groups[0], + status=ClusterStatusChoices.STATUS_PLANNED, + ), + Cluster( + name='Cluster 2', + type=cluster_types[0], + group=cluster_groups[0], + status=ClusterStatusChoices.STATUS_PLANNED, + ), + Cluster( + name='Cluster 3', + type=cluster_types[0], + group=cluster_groups[0], + status=ClusterStatusChoices.STATUS_PLANNED, + ), ) for cluster in clusters: cluster.save() @@ -169,9 +184,25 @@ class VirtualMachineTest(APIViewTestCases.APIViewTestCase): device2 = create_test_device('device2', site=sites[1], cluster=clusters[1]) virtual_machines = ( - VirtualMachine(name='Virtual Machine 1', site=sites[0], cluster=clusters[0], device=device1, local_context_data={'A': 1}), - VirtualMachine(name='Virtual Machine 2', site=sites[0], cluster=clusters[0], local_context_data={'B': 2}), - VirtualMachine(name='Virtual Machine 3', site=sites[0], cluster=clusters[0], local_context_data={'C': 3}), + VirtualMachine( + name='Virtual Machine 1', + site=sites[0], + cluster=clusters[0], + device=device1, + local_context_data={'A': 1}, + ), + VirtualMachine( + name='Virtual Machine 2', + site=sites[0], + cluster=clusters[0], + local_context_data={'B': 2 + }), + VirtualMachine( + name='Virtual Machine 3', + site=sites[0], + cluster=clusters[0], + local_context_data={'C': 3} + ), ) VirtualMachine.objects.bulk_create(virtual_machines) diff --git a/netbox/virtualization/tests/test_views.py b/netbox/virtualization/tests/test_views.py index dfd7e041c..3c8d7eadc 100644 --- a/netbox/virtualization/tests/test_views.py +++ b/netbox/virtualization/tests/test_views.py @@ -117,9 +117,27 @@ class ClusterTestCase(ViewTestCases.PrimaryObjectViewTestCase): ClusterType.objects.bulk_create(clustertypes) clusters = ( - Cluster(name='Cluster 1', group=clustergroups[0], type=clustertypes[0], status=ClusterStatusChoices.STATUS_ACTIVE, scope=sites[0]), - Cluster(name='Cluster 2', group=clustergroups[0], type=clustertypes[0], status=ClusterStatusChoices.STATUS_ACTIVE, scope=sites[0]), - Cluster(name='Cluster 3', group=clustergroups[0], type=clustertypes[0], status=ClusterStatusChoices.STATUS_ACTIVE, scope=sites[0]), + Cluster( + name='Cluster 1', + group=clustergroups[0], + type=clustertypes[0], + status=ClusterStatusChoices.STATUS_ACTIVE, + scope=sites[0], + ), + Cluster( + name='Cluster 2', + group=clustergroups[0], + type=clustertypes[0], + status=ClusterStatusChoices.STATUS_ACTIVE, + scope=sites[0], + ), + Cluster( + name='Cluster 3', + group=clustergroups[0], + type=clustertypes[0], + status=ClusterStatusChoices.STATUS_ACTIVE, + scope=sites[0], + ), ) for cluster in clusters: cluster.save() @@ -214,9 +232,30 @@ class VirtualMachineTestCase(ViewTestCases.PrimaryObjectViewTestCase): ) virtual_machines = ( - VirtualMachine(name='Virtual Machine 1', site=sites[0], cluster=clusters[0], device=devices[0], role=roles[0], platform=platforms[0]), - VirtualMachine(name='Virtual Machine 2', site=sites[0], cluster=clusters[0], device=devices[0], role=roles[0], platform=platforms[0]), - VirtualMachine(name='Virtual Machine 3', site=sites[0], cluster=clusters[0], device=devices[0], role=roles[0], platform=platforms[0]), + VirtualMachine( + name='Virtual Machine 1', + site=sites[0], + cluster=clusters[0], + device=devices[0], + role=roles[0], + platform=platforms[0], + ), + VirtualMachine( + name='Virtual Machine 2', + site=sites[0], + cluster=clusters[0], + device=devices[0], + role=roles[0], + platform=platforms[0], + ), + VirtualMachine( + name='Virtual Machine 3', + site=sites[0], + cluster=clusters[0], + device=devices[0], + role=roles[0], + platform=platforms[0], + ), ) VirtualMachine.objects.bulk_create(virtual_machines) diff --git a/netbox/virtualization/views.py b/netbox/virtualization/views.py index 605de0911..ccba12239 100644 --- a/netbox/virtualization/views.py +++ b/netbox/virtualization/views.py @@ -177,7 +177,11 @@ class ClusterView(generic.ObjectView): queryset = Cluster.objects.all() def get_extra_context(self, request, instance): - return instance.virtual_machines.aggregate(vcpus_sum=Sum('vcpus'), memory_sum=Sum('memory'), disk_sum=Sum('disk')) + return instance.virtual_machines.aggregate( + vcpus_sum=Sum('vcpus'), + memory_sum=Sum('memory'), + disk_sum=Sum('disk') + ) @register_model_view(Cluster, 'virtualmachines', path='virtual-machines') diff --git a/netbox/vpn/api/serializers_/crypto.py b/netbox/vpn/api/serializers_/crypto.py index c11b8de2b..fbd04c230 100644 --- a/netbox/vpn/api/serializers_/crypto.py +++ b/netbox/vpn/api/serializers_/crypto.py @@ -74,7 +74,8 @@ class IPSecProposalSerializer(NetBoxModelSerializer): model = IPSecProposal fields = ( 'id', 'url', 'display_url', 'display', 'name', 'description', 'encryption_algorithm', - 'authentication_algorithm', 'sa_lifetime_seconds', 'sa_lifetime_data', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', + 'authentication_algorithm', 'sa_lifetime_seconds', 'sa_lifetime_data', 'comments', 'tags', 'custom_fields', + 'created', 'last_updated', ) brief_fields = ('id', 'url', 'display', 'name', 'description') diff --git a/netbox/vpn/migrations/0001_initial.py b/netbox/vpn/migrations/0001_initial.py index 681474837..b44ae3e52 100644 --- a/netbox/vpn/migrations/0001_initial.py +++ b/netbox/vpn/migrations/0001_initial.py @@ -5,7 +5,6 @@ import utilities.json class Migration(migrations.Migration): - initial = True dependencies = [ @@ -23,7 +22,10 @@ class Migration(migrations.Migration): ('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=utilities.json.CustomFieldJSONEncoder), + ), ('description', models.CharField(blank=True, max_length=200)), ('comments', models.TextField(blank=True)), ('name', models.CharField(max_length=100, unique=True)), @@ -46,7 +48,10 @@ class Migration(migrations.Migration): ('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=utilities.json.CustomFieldJSONEncoder), + ), ('description', models.CharField(blank=True, max_length=200)), ('comments', models.TextField(blank=True)), ('name', models.CharField(max_length=100, unique=True)), @@ -70,7 +75,6 @@ class Migration(migrations.Migration): name='tags', field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), ), - # IPSec migrations.CreateModel( name='IPSecProposal', @@ -78,7 +82,10 @@ class Migration(migrations.Migration): ('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=utilities.json.CustomFieldJSONEncoder), + ), ('description', models.CharField(blank=True, max_length=200)), ('comments', models.TextField(blank=True)), ('name', models.CharField(max_length=100, unique=True)), @@ -100,7 +107,10 @@ class Migration(migrations.Migration): ('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=utilities.json.CustomFieldJSONEncoder), + ), ('description', models.CharField(blank=True, max_length=200)), ('comments', models.TextField(blank=True)), ('name', models.CharField(max_length=100, unique=True)), @@ -128,13 +138,26 @@ class Migration(migrations.Migration): ('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=utilities.json.CustomFieldJSONEncoder), + ), ('description', models.CharField(blank=True, max_length=200)), ('comments', models.TextField(blank=True)), ('name', models.CharField(max_length=100, unique=True)), ('mode', models.CharField()), - ('ike_policy', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='ipsec_profiles', to='vpn.ikepolicy')), - ('ipsec_policy', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='ipsec_profiles', to='vpn.ipsecpolicy')), + ( + 'ike_policy', + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, related_name='ipsec_profiles', to='vpn.ikepolicy' + ), + ), + ( + 'ipsec_policy', + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, related_name='ipsec_profiles', to='vpn.ipsecpolicy' + ), + ), ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), ], options={ @@ -143,7 +166,6 @@ class Migration(migrations.Migration): 'ordering': ('name',), }, ), - # Tunnels migrations.CreateModel( name='TunnelGroup', @@ -151,7 +173,10 @@ class Migration(migrations.Migration): ('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=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)), @@ -173,17 +198,47 @@ class Migration(migrations.Migration): ('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=utilities.json.CustomFieldJSONEncoder), + ), ('description', models.CharField(blank=True, max_length=200)), ('comments', models.TextField(blank=True)), ('name', models.CharField(max_length=100, unique=True)), ('status', models.CharField(default='active', max_length=50)), - ('group', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='tunnels', to='vpn.tunnelgroup')), + ( + 'group', + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='tunnels', + to='vpn.tunnelgroup', + ), + ), ('encapsulation', models.CharField(max_length=50)), ('tunnel_id', models.PositiveBigIntegerField(blank=True, null=True)), - ('ipsec_profile', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='tunnels', to='vpn.ipsecprofile')), + ( + 'ipsec_profile', + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='tunnels', + to='vpn.ipsecprofile', + ), + ), ('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='tunnels', to='tenancy.tenant')), + ( + 'tenant', + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='tunnels', + to='tenancy.tenant', + ), + ), ], options={ 'verbose_name': 'tunnel', @@ -197,7 +252,9 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='tunnel', - constraint=models.UniqueConstraint(condition=models.Q(('group__isnull', True)), fields=('name',), name='vpn_tunnel_name'), + constraint=models.UniqueConstraint( + condition=models.Q(('group__isnull', True)), fields=('name',), name='vpn_tunnel_name' + ), ), migrations.CreateModel( name='TunnelTermination', @@ -205,13 +262,35 @@ class Migration(migrations.Migration): ('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=utilities.json.CustomFieldJSONEncoder), + ), ('role', models.CharField(default='peer', max_length=50)), ('termination_id', models.PositiveBigIntegerField(blank=True, null=True)), - ('termination_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype')), - ('outside_ip', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='tunnel_termination', to='ipam.ipaddress')), + ( + 'termination_type', + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype' + ), + ), + ( + 'outside_ip', + models.OneToOneField( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='tunnel_termination', + to='ipam.ipaddress', + ), + ), ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), - ('tunnel', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='terminations', to='vpn.tunnel')), + ( + 'tunnel', + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, related_name='terminations', to='vpn.tunnel' + ), + ), ], options={ 'verbose_name': 'tunnel termination', @@ -225,6 +304,10 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='tunneltermination', - constraint=models.UniqueConstraint(fields=('termination_type', 'termination_id'), name='vpn_tunneltermination_termination', violation_error_message='An object may be terminated to only one tunnel at a time.'), + constraint=models.UniqueConstraint( + fields=('termination_type', 'termination_id'), + name='vpn_tunneltermination_termination', + violation_error_message='An object may be terminated to only one tunnel at a time.', + ), ), ] diff --git a/netbox/vpn/migrations/0002_move_l2vpn.py b/netbox/vpn/migrations/0002_move_l2vpn.py index b83ea4655..5f1480dce 100644 --- a/netbox/vpn/migrations/0002_move_l2vpn.py +++ b/netbox/vpn/migrations/0002_move_l2vpn.py @@ -5,7 +5,6 @@ import utilities.json class Migration(migrations.Migration): - dependencies = [ ('extras', '0099_cachedvalue_ordering'), ('contenttypes', '0002_remove_content_type_name'), @@ -23,17 +22,35 @@ class Migration(migrations.Migration): ('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=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)), - ('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')), + ( + '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')), + ( + 'tenant', + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='l2vpns', + to='tenancy.tenant', + ), + ), ], options={ 'verbose_name': 'L2VPN', @@ -47,10 +64,33 @@ class Migration(migrations.Migration): ('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=utilities.json.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='vpn.l2vpn')), + ( + '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='vpn.l2vpn' + ), + ), ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), ], options={ @@ -66,12 +106,13 @@ class Migration(migrations.Migration): migrations.AddConstraint( model_name='l2vpntermination', constraint=models.UniqueConstraint( - fields=('assigned_object_type', 'assigned_object_id'), - name='vpn_l2vpntermination_assigned_object' + fields=('assigned_object_type', 'assigned_object_id'), name='vpn_l2vpntermination_assigned_object' ), ), migrations.AddIndex( model_name='l2vpntermination', - index=models.Index(fields=['assigned_object_type', 'assigned_object_id'], name='vpn_l2vpnte_assigne_9c55f8_idx'), + index=models.Index( + fields=['assigned_object_type', 'assigned_object_id'], name='vpn_l2vpnte_assigne_9c55f8_idx' + ), ), ] diff --git a/netbox/vpn/migrations/0003_ipaddress_multiple_tunnel_terminations.py b/netbox/vpn/migrations/0003_ipaddress_multiple_tunnel_terminations.py index 2747669ae..ce042b4db 100644 --- a/netbox/vpn/migrations/0003_ipaddress_multiple_tunnel_terminations.py +++ b/netbox/vpn/migrations/0003_ipaddress_multiple_tunnel_terminations.py @@ -5,7 +5,6 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ ('ipam', '0069_gfk_indexes'), ('vpn', '0002_move_l2vpn'), @@ -15,6 +14,12 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='tunneltermination', name='outside_ip', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='tunnel_terminations', to='ipam.ipaddress'), + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='tunnel_terminations', + to='ipam.ipaddress', + ), ), ] diff --git a/netbox/vpn/migrations/0004_alter_ikepolicy_mode.py b/netbox/vpn/migrations/0004_alter_ikepolicy_mode.py index 40dd4f99e..44bf4d35b 100644 --- a/netbox/vpn/migrations/0004_alter_ikepolicy_mode.py +++ b/netbox/vpn/migrations/0004_alter_ikepolicy_mode.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('vpn', '0003_ipaddress_multiple_tunnel_terminations'), ] diff --git a/netbox/vpn/migrations/0005_rename_indexes.py b/netbox/vpn/migrations/0005_rename_indexes.py index 805b380cc..f24106c1f 100644 --- a/netbox/vpn/migrations/0005_rename_indexes.py +++ b/netbox/vpn/migrations/0005_rename_indexes.py @@ -2,43 +2,56 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ ('vpn', '0004_alter_ikepolicy_mode'), ] operations = [ - # Rename vpn_l2vpn constraints - migrations.RunSQL("ALTER TABLE vpn_l2vpn RENAME CONSTRAINT ipam_l2vpn_tenant_id_bb2564a6_fk_tenancy_tenant_id TO vpn_l2vpn_tenant_id_57ec8f92_fk_tenancy_tenant_id"), - + migrations.RunSQL(( + 'ALTER TABLE vpn_l2vpn ' + 'RENAME CONSTRAINT ipam_l2vpn_tenant_id_bb2564a6_fk_tenancy_tenant_id ' + 'TO vpn_l2vpn_tenant_id_57ec8f92_fk_tenancy_tenant_id' + )), # Rename ipam_l2vpn_* sequences - migrations.RunSQL("ALTER TABLE ipam_l2vpn_export_targets_id_seq RENAME TO vpn_l2vpn_export_targets_id_seq"), - migrations.RunSQL("ALTER TABLE ipam_l2vpn_id_seq RENAME TO vpn_l2vpn_id_seq"), - migrations.RunSQL("ALTER TABLE ipam_l2vpn_import_targets_id_seq RENAME TO vpn_l2vpn_import_targets_id_seq"), - + migrations.RunSQL('ALTER TABLE ipam_l2vpn_export_targets_id_seq RENAME TO vpn_l2vpn_export_targets_id_seq'), + migrations.RunSQL('ALTER TABLE ipam_l2vpn_id_seq RENAME TO vpn_l2vpn_id_seq'), + migrations.RunSQL('ALTER TABLE ipam_l2vpn_import_targets_id_seq RENAME TO vpn_l2vpn_import_targets_id_seq'), # Rename ipam_l2vpn_* indexes - migrations.RunSQL("ALTER INDEX ipam_l2vpn_pkey RENAME TO vpn_l2vpn_pkey"), - migrations.RunSQL("ALTER INDEX ipam_l2vpn_name_5e1c080f_like RENAME TO vpn_l2vpn_name_8824eda5_like"), - migrations.RunSQL("ALTER INDEX ipam_l2vpn_name_key RENAME TO vpn_l2vpn_name_key"), - migrations.RunSQL("ALTER INDEX ipam_l2vpn_slug_24008406_like RENAME TO vpn_l2vpn_slug_76b5a174_like"), - migrations.RunSQL("ALTER INDEX ipam_l2vpn_tenant_id_bb2564a6 RENAME TO vpn_l2vpn_tenant_id_57ec8f92"), + migrations.RunSQL('ALTER INDEX ipam_l2vpn_pkey RENAME TO vpn_l2vpn_pkey'), + migrations.RunSQL('ALTER INDEX ipam_l2vpn_name_5e1c080f_like RENAME TO vpn_l2vpn_name_8824eda5_like'), + migrations.RunSQL('ALTER INDEX ipam_l2vpn_name_key RENAME TO vpn_l2vpn_name_key'), + migrations.RunSQL('ALTER INDEX ipam_l2vpn_slug_24008406_like RENAME TO vpn_l2vpn_slug_76b5a174_like'), + migrations.RunSQL('ALTER INDEX ipam_l2vpn_tenant_id_bb2564a6 RENAME TO vpn_l2vpn_tenant_id_57ec8f92'), # The unique index for L2VPN.slug may have one of two names, depending on how it was created, # so we check for both. - migrations.RunSQL("ALTER INDEX IF EXISTS ipam_l2vpn_slug_24008406_uniq RENAME TO vpn_l2vpn_slug_76b5a174_uniq"), - migrations.RunSQL("ALTER INDEX IF EXISTS ipam_l2vpn_slug_key RENAME TO vpn_l2vpn_slug_key"), - + migrations.RunSQL('ALTER INDEX IF EXISTS ipam_l2vpn_slug_24008406_uniq RENAME TO vpn_l2vpn_slug_76b5a174_uniq'), + migrations.RunSQL('ALTER INDEX IF EXISTS ipam_l2vpn_slug_key RENAME TO vpn_l2vpn_slug_key'), # Rename vpn_l2vpntermination constraints - migrations.RunSQL("ALTER TABLE vpn_l2vpntermination RENAME CONSTRAINT ipam_l2vpntermination_assigned_object_id_check TO vpn_l2vpntermination_assigned_object_id_check"), - migrations.RunSQL("ALTER TABLE vpn_l2vpntermination RENAME CONSTRAINT ipam_l2vpnterminatio_assigned_object_type_3923c124_fk_django_co TO vpn_l2vpntermination_assigned_object_type_id_f063b865_fk_django_co"), - migrations.RunSQL("ALTER TABLE vpn_l2vpntermination RENAME CONSTRAINT ipam_l2vpntermination_l2vpn_id_9e570aa1_fk_ipam_l2vpn_id TO vpn_l2vpntermination_l2vpn_id_f5367bbe_fk_vpn_l2vpn_id"), - + migrations.RunSQL(( + 'ALTER TABLE vpn_l2vpntermination ' + 'RENAME CONSTRAINT ipam_l2vpntermination_assigned_object_id_check ' + 'TO vpn_l2vpntermination_assigned_object_id_check' + )), + migrations.RunSQL(( + 'ALTER TABLE vpn_l2vpntermination ' + 'RENAME CONSTRAINT ipam_l2vpnterminatio_assigned_object_type_3923c124_fk_django_co ' + 'TO vpn_l2vpntermination_assigned_object_type_id_f063b865_fk_django_co' + )), + migrations.RunSQL(( + 'ALTER TABLE vpn_l2vpntermination ' + 'RENAME CONSTRAINT ipam_l2vpntermination_l2vpn_id_9e570aa1_fk_ipam_l2vpn_id ' + 'TO vpn_l2vpntermination_l2vpn_id_f5367bbe_fk_vpn_l2vpn_id' + )), # Rename ipam_l2vpn_termination_* sequences - migrations.RunSQL("ALTER TABLE ipam_l2vpntermination_id_seq RENAME TO vpn_l2vpntermination_id_seq"), - + migrations.RunSQL('ALTER TABLE ipam_l2vpntermination_id_seq RENAME TO vpn_l2vpntermination_id_seq'), # Rename ipam_l2vpn_* indexes - migrations.RunSQL("ALTER INDEX ipam_l2vpntermination_pkey RENAME TO vpn_l2vpntermination_pkey"), - migrations.RunSQL("ALTER INDEX ipam_l2vpntermination_assigned_object_type_id_3923c124 RENAME TO vpn_l2vpntermination_assigned_object_type_id_f063b865"), - migrations.RunSQL("ALTER INDEX ipam_l2vpntermination_l2vpn_id_9e570aa1 RENAME TO vpn_l2vpntermination_l2vpn_id_f5367bbe"), - + migrations.RunSQL('ALTER INDEX ipam_l2vpntermination_pkey RENAME TO vpn_l2vpntermination_pkey'), + migrations.RunSQL(( + 'ALTER INDEX ipam_l2vpntermination_assigned_object_type_id_3923c124 ' + 'RENAME TO vpn_l2vpntermination_assigned_object_type_id_f063b865' + )), + migrations.RunSQL( + 'ALTER INDEX ipam_l2vpntermination_l2vpn_id_9e570aa1 RENAME TO vpn_l2vpntermination_l2vpn_id_f5367bbe' + ), ] diff --git a/netbox/vpn/migrations/0006_charfield_null_choices.py b/netbox/vpn/migrations/0006_charfield_null_choices.py index 1943c466f..784b66d72 100644 --- a/netbox/vpn/migrations/0006_charfield_null_choices.py +++ b/netbox/vpn/migrations/0006_charfield_null_choices.py @@ -16,7 +16,6 @@ def set_null_values(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('vpn', '0005_rename_indexes'), ] @@ -42,8 +41,5 @@ class Migration(migrations.Migration): name='encryption_algorithm', field=models.CharField(blank=True, null=True), ), - migrations.RunPython( - code=set_null_values, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=set_null_values, reverse_code=migrations.RunPython.noop), ] diff --git a/netbox/vpn/migrations/0007_natural_ordering.py b/netbox/vpn/migrations/0007_natural_ordering.py index 01dd4620f..3eb8ab5a9 100644 --- a/netbox/vpn/migrations/0007_natural_ordering.py +++ b/netbox/vpn/migrations/0007_natural_ordering.py @@ -2,7 +2,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('vpn', '0006_charfield_null_choices'), ('dcim', '0197_natural_sort_collation'), diff --git a/netbox/wireless/api/serializers_/wirelesslans.py b/netbox/wireless/api/serializers_/wirelesslans.py index 637089277..68f79daf6 100644 --- a/netbox/wireless/api/serializers_/wirelesslans.py +++ b/netbox/wireless/api/serializers_/wirelesslans.py @@ -52,9 +52,9 @@ class WirelessLANSerializer(NetBoxModelSerializer): class Meta: model = WirelessLAN fields = [ - 'id', 'url', 'display_url', 'display', 'ssid', 'description', 'group', 'status', 'vlan', 'scope_type', 'scope_id', 'scope', - 'tenant', 'auth_type', 'auth_cipher', 'auth_psk', 'description', 'comments', 'tags', 'custom_fields', - 'created', 'last_updated', + 'id', 'url', 'display_url', 'display', 'ssid', 'description', 'group', 'status', 'vlan', 'scope_type', + 'scope_id', 'scope', 'tenant', 'auth_type', 'auth_cipher', 'auth_psk', 'description', 'comments', 'tags', + 'custom_fields', 'created', 'last_updated', ] brief_fields = ('id', 'url', 'display', 'ssid', 'description') diff --git a/netbox/wireless/forms/bulk_import.py b/netbox/wireless/forms/bulk_import.py index f23ccf203..1fece7e46 100644 --- a/netbox/wireless/forms/bulk_import.py +++ b/netbox/wireless/forms/bulk_import.py @@ -76,8 +76,8 @@ class WirelessLANImportForm(ScopedImportForm, NetBoxModelImportForm): class Meta: model = WirelessLAN fields = ( - 'ssid', 'group', 'status', 'vlan', 'tenant', 'auth_type', 'auth_cipher', 'auth_psk', 'scope_type', 'scope_id', - 'description', 'comments', 'tags', + 'ssid', 'group', 'status', 'vlan', 'tenant', 'auth_type', 'auth_cipher', 'auth_psk', 'scope_type', + 'scope_id', 'description', 'comments', 'tags', ) labels = { 'scope_id': _('Scope ID'), diff --git a/netbox/wireless/migrations/0001_squashed_0008.py b/netbox/wireless/migrations/0001_squashed_0008.py index 2326f5cf7..8886580e1 100644 --- a/netbox/wireless/migrations/0001_squashed_0008.py +++ b/netbox/wireless/migrations/0001_squashed_0008.py @@ -8,7 +8,6 @@ import wireless.models class Migration(migrations.Migration): - replaces = [ ('wireless', '0001_wireless'), ('wireless', '0002_standardize_id_fields'), @@ -17,7 +16,7 @@ class Migration(migrations.Migration): ('wireless', '0005_wirelesslink_interface_types'), ('wireless', '0006_unique_constraints'), ('wireless', '0007_standardize_description_comments'), - ('wireless', '0008_wirelesslan_status') + ('wireless', '0008_wirelesslan_status'), ] dependencies = [ @@ -33,7 +32,10 @@ class Migration(migrations.Migration): fields=[ ('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=utilities.json.CustomFieldJSONEncoder), + ), ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), ('name', models.CharField(max_length=100, unique=True)), ('slug', models.SlugField(max_length=100, unique=True)), @@ -43,7 +45,16 @@ class Migration(migrations.Migration): ('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')), + ( + 'parent', + mptt.fields.TreeForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name='children', + to='wireless.wirelesslangroup', + ), + ), ], options={ 'ordering': ('name', 'pk'), @@ -56,17 +67,43 @@ class Migration(migrations.Migration): fields=[ ('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=utilities.json.CustomFieldJSONEncoder), + ), ('id', models.BigAutoField(auto_created=True, 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')), + ( + '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)), ('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)), ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), - ('vlan', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='ipam.vlan')), - ('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' + ), + ), + ( + 'tenant', + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='wireless_lans', + to='tenancy.tenant', + ), + ), ], options={ 'verbose_name': 'Wireless LAN', @@ -78,7 +115,10 @@ class Migration(migrations.Migration): fields=[ ('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=utilities.json.CustomFieldJSONEncoder), + ), ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), ('ssid', models.CharField(blank=True, max_length=32)), ('status', models.CharField(default='connected', max_length=50)), @@ -86,12 +126,55 @@ class Migration(migrations.Migration): ('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=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')), + ( + '_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')), + ( + 'tenant', + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='wireless_links', + to='tenancy.tenant', + ), + ), ], options={ 'ordering': ['pk'], @@ -100,11 +183,15 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='wirelesslangroup', - constraint=models.UniqueConstraint(fields=('parent', 'name'), name='wireless_wirelesslangroup_unique_parent_name'), + 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'), + constraint=models.UniqueConstraint( + fields=('interface_a', 'interface_b'), name='wireless_wirelesslink_unique_interfaces' + ), ), migrations.AddField( model_name='wirelesslan', diff --git a/netbox/wireless/migrations/0009_wirelesslink_distance.py b/netbox/wireless/migrations/0009_wirelesslink_distance.py index 6a778ef00..6ddf4ab44 100644 --- a/netbox/wireless/migrations/0009_wirelesslink_distance.py +++ b/netbox/wireless/migrations/0009_wirelesslink_distance.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('wireless', '0001_squashed_0008'), ] diff --git a/netbox/wireless/migrations/0010_charfield_null_choices.py b/netbox/wireless/migrations/0010_charfield_null_choices.py index 9bfdc54ed..f0394618a 100644 --- a/netbox/wireless/migrations/0010_charfield_null_choices.py +++ b/netbox/wireless/migrations/0010_charfield_null_choices.py @@ -16,7 +16,6 @@ def set_null_values(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('wireless', '0009_wirelesslink_distance'), ] @@ -47,8 +46,5 @@ class Migration(migrations.Migration): name='distance_unit', field=models.CharField(blank=True, max_length=50, null=True), ), - migrations.RunPython( - code=set_null_values, - reverse_code=migrations.RunPython.noop - ), + migrations.RunPython(code=set_null_values, reverse_code=migrations.RunPython.noop), ] diff --git a/netbox/wireless/migrations/0011_wirelesslan__location_wirelesslan__region_and_more.py b/netbox/wireless/migrations/0011_wirelesslan__location_wirelesslan__region_and_more.py index ea4470641..334d41bdd 100644 --- a/netbox/wireless/migrations/0011_wirelesslan__location_wirelesslan__region_and_more.py +++ b/netbox/wireless/migrations/0011_wirelesslan__location_wirelesslan__region_and_more.py @@ -5,7 +5,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('contenttypes', '0002_remove_content_type_name'), ('dcim', '0196_qinq_svlan'), diff --git a/netbox/wireless/migrations/0012_alter_wirelesslan__location_and_more.py b/netbox/wireless/migrations/0012_alter_wirelesslan__location_and_more.py index 7edaff92b..21f118bd0 100644 --- a/netbox/wireless/migrations/0012_alter_wirelesslan__location_and_more.py +++ b/netbox/wireless/migrations/0012_alter_wirelesslan__location_and_more.py @@ -5,7 +5,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('dcim', '0196_qinq_svlan'), ('wireless', '0011_wirelesslan__location_wirelesslan__region_and_more'), diff --git a/netbox/wireless/migrations/0013_natural_ordering.py b/netbox/wireless/migrations/0013_natural_ordering.py index e33c87c60..7caede643 100644 --- a/netbox/wireless/migrations/0013_natural_ordering.py +++ b/netbox/wireless/migrations/0013_natural_ordering.py @@ -2,7 +2,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('wireless', '0012_alter_wirelesslan__location_and_more'), ('dcim', '0197_natural_sort_collation'), diff --git a/netbox/wireless/tables/wirelesslan.py b/netbox/wireless/tables/wirelesslan.py index 40f52f8a5..fe9c0f5fa 100644 --- a/netbox/wireless/tables/wirelesslan.py +++ b/netbox/wireless/tables/wirelesslan.py @@ -72,7 +72,8 @@ class WirelessLANTable(TenancyColumnsMixin, NetBoxTable): model = WirelessLAN fields = ( 'pk', 'ssid', 'group', 'status', 'tenant', 'tenant_group', 'vlan', 'interface_count', 'auth_type', - 'auth_cipher', 'auth_psk', 'scope', 'scope_type', 'description', 'comments', 'tags', 'created', 'last_updated', + 'auth_cipher', 'auth_psk', 'scope', 'scope_type', 'description', 'comments', 'tags', 'created', + 'last_updated', ) default_columns = ('pk', 'ssid', 'group', 'status', 'description', 'vlan', 'auth_type', 'interface_count') diff --git a/netbox/wireless/tests/test_filtersets.py b/netbox/wireless/tests/test_filtersets.py index 76ef4e220..27aab83d8 100644 --- a/netbox/wireless/tests/test_filtersets.py +++ b/netbox/wireless/tests/test_filtersets.py @@ -27,8 +27,18 @@ class WirelessLANGroupTestCase(TestCase, ChangeLoggedFilterSetTests): group.save() groups = ( - WirelessLANGroup(name='Wireless LAN Group 1A', slug='wireless-lan-group-1a', parent=parent_groups[0], description='foobar1'), - WirelessLANGroup(name='Wireless LAN Group 1B', slug='wireless-lan-group-1b', parent=parent_groups[0], description='foobar2'), + WirelessLANGroup( + name='Wireless LAN Group 1A', + slug='wireless-lan-group-1a', + parent=parent_groups[0], + description='foobar1', + ), + WirelessLANGroup( + name='Wireless LAN Group 1B', + slug='wireless-lan-group-1b', + parent=parent_groups[0], + description='foobar2', + ), WirelessLANGroup(name='Wireless LAN Group 2A', slug='wireless-lan-group-2a', parent=parent_groups[1]), WirelessLANGroup(name='Wireless LAN Group 2B', slug='wireless-lan-group-2b', parent=parent_groups[1]), WirelessLANGroup(name='Wireless LAN Group 3A', slug='wireless-lan-group-3a', parent=parent_groups[2]), diff --git a/netbox/wireless/tests/test_views.py b/netbox/wireless/tests/test_views.py index 713ba81d7..51af37364 100644 --- a/netbox/wireless/tests/test_views.py +++ b/netbox/wireless/tests/test_views.py @@ -113,9 +113,20 @@ class WirelessLANTestCase(ViewTestCases.PrimaryObjectViewTestCase): cls.csv_data = ( "group,ssid,status,tenant,scope_type,scope_id", - f"Wireless LAN Group 2,WLAN4,{WirelessLANStatusChoices.STATUS_ACTIVE},{tenants[0].name},,", - f"Wireless LAN Group 2,WLAN5,{WirelessLANStatusChoices.STATUS_DISABLED},{tenants[1].name},dcim.site,{sites[0].pk}", - f"Wireless LAN Group 2,WLAN6,{WirelessLANStatusChoices.STATUS_RESERVED},{tenants[2].name},dcim.site,{sites[1].pk}", + "Wireless LAN Group 2,WLAN4,{status},{tenant},,".format( + status=WirelessLANStatusChoices.STATUS_ACTIVE, + tenant=tenants[0].name + ), + "Wireless LAN Group 2,WLAN5,{status},{tenant},dcim.site,{site}".format( + status=WirelessLANStatusChoices.STATUS_DISABLED, + tenant=tenants[1].name, + site=sites[0].pk + ), + "Wireless LAN Group 2,WLAN6,{status},{tenant},dcim.site,{site}".format( + status=WirelessLANStatusChoices.STATUS_RESERVED, + tenant=tenants[2].name, + site=sites[1].pk + ), ) cls.csv_update_data = ( @@ -157,11 +168,17 @@ class WirelessLinkTestCase(ViewTestCases.PrimaryObjectViewTestCase): ] Interface.objects.bulk_create(interfaces) - wirelesslink1 = WirelessLink(interface_a=interfaces[0], interface_b=interfaces[1], ssid='LINK1', tenant=tenants[0]) + wirelesslink1 = WirelessLink( + interface_a=interfaces[0], interface_b=interfaces[1], ssid='LINK1', tenant=tenants[0] + ) wirelesslink1.save() - wirelesslink2 = WirelessLink(interface_a=interfaces[2], interface_b=interfaces[3], ssid='LINK2', tenant=tenants[0]) + wirelesslink2 = WirelessLink( + interface_a=interfaces[2], interface_b=interfaces[3], ssid='LINK2', tenant=tenants[0] + ) wirelesslink2.save() - wirelesslink3 = WirelessLink(interface_a=interfaces[4], interface_b=interfaces[5], ssid='LINK3', tenant=tenants[0]) + wirelesslink3 = WirelessLink( + interface_a=interfaces[4], interface_b=interfaces[5], ssid='LINK3', tenant=tenants[0] + ) wirelesslink3.save() tags = create_tags('Alpha', 'Bravo', 'Charlie') diff --git a/ruff.toml b/ruff.toml index 94a0e1c61..12dac331e 100644 --- a/ruff.toml +++ b/ruff.toml @@ -1,4 +1,15 @@ +exclude = [ + "netbox/project-static/**" +] +line-length = 120 + [lint] -extend-select = ["E1", "E2", "E3", "W"] -ignore = ["E501", "F403", "F405"] +extend-select = ["E1", "E2", "E3", "E501", "W"] +ignore = ["F403", "F405"] preview = true + +[lint.per-file-ignores] +"template_code.py" = ["E501"] + +[format] +quote-style = "single"