From d6adebbe6b3def7c5cf30ef72facba4df9e99321 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Date: Wed, 30 Oct 2024 09:10:57 -0700 Subject: [PATCH] 9604 scope->termination --- docs/models/circuits/circuittermination.md | 2 +- netbox/circuits/api/serializers_/circuits.py | 38 ++++++------ netbox/circuits/constants.py | 4 +- netbox/circuits/filtersets.py | 4 +- netbox/circuits/forms/bulk_edit.py | 30 +++++----- netbox/circuits/forms/bulk_import.py | 14 ++--- netbox/circuits/forms/filtersets.py | 2 +- netbox/circuits/forms/model_forms.py | 40 ++++++------- netbox/circuits/graphql/types.py | 8 +-- ...> 0047_circuittermination__termination.py} | 14 ++--- ...48_circuitterminations_cached_relations.py | 12 ++-- netbox/circuits/models/circuits.py | 60 +++++++++---------- netbox/circuits/tests/test_api.py | 16 ++--- netbox/circuits/tests/test_filtersets.py | 36 +++++------ netbox/circuits/tests/test_views.py | 26 ++++---- netbox/dcim/tests/test_cablepaths.py | 30 +++++----- netbox/dcim/tests/test_filtersets.py | 2 +- netbox/dcim/tests/test_models.py | 6 +- .../inc/circuit_termination_fields.html | 8 +-- 19 files changed, 176 insertions(+), 176 deletions(-) rename netbox/circuits/migrations/{0047_circuittermination__scope.py => 0047_circuittermination__termination.py} (81%) diff --git a/docs/models/circuits/circuittermination.md b/docs/models/circuits/circuittermination.md index 5ab1a6776..f4e6cbbc5 100644 --- a/docs/models/circuits/circuittermination.md +++ b/docs/models/circuits/circuittermination.md @@ -21,7 +21,7 @@ Designates the termination as forming either the A or Z end of the circuit. If selected, the circuit termination will be considered "connected" even if no cable has been connected to it in NetBox. -### Scope +### Termination The [region](../dcim/region.md), [site group](../dcim/sitegroup.md), [site](../dcim/site.md) or [location](../dcim/location.md) with which this circuit termination is associated. Once created, a cable can be connected between the circuit termination and a device interface (or similar component). diff --git a/netbox/circuits/api/serializers_/circuits.py b/netbox/circuits/api/serializers_/circuits.py index 2d4dad9a8..96a686a65 100644 --- a/netbox/circuits/api/serializers_/circuits.py +++ b/netbox/circuits/api/serializers_/circuits.py @@ -3,7 +3,7 @@ from drf_spectacular.utils import extend_schema_field from rest_framework import serializers from circuits.choices import CircuitPriorityChoices, CircuitStatusChoices -from circuits.constants import CIRCUIT_TERMINATION_SCOPE_TYPES +from circuits.constants import CIRCUIT_TERMINATION_TERMINATION_TYPES from circuits.models import Circuit, CircuitGroup, CircuitGroupAssignment, CircuitTermination, CircuitType from dcim.api.serializers_.cables import CabledObjectSerializer from netbox.api.fields import ChoiceField, ContentTypeField, RelatedObjectCountField @@ -38,32 +38,32 @@ class CircuitTypeSerializer(NetBoxModelSerializer): class CircuitCircuitTerminationSerializer(WritableNestedSerializer): - scope_type = ContentTypeField( + termination_type = ContentTypeField( queryset=ContentType.objects.filter( - model__in=CIRCUIT_TERMINATION_SCOPE_TYPES + model__in=CIRCUIT_TERMINATION_TERMINATION_TYPES ), allow_null=True, required=False, default=None ) - scope_id = serializers.IntegerField(allow_null=True, required=False, default=None) - scope = serializers.SerializerMethodField(read_only=True) + termination_id = serializers.IntegerField(allow_null=True, required=False, default=None) + termination = serializers.SerializerMethodField(read_only=True) provider_network = ProviderNetworkSerializer(nested=True, allow_null=True) class Meta: model = CircuitTermination fields = [ - 'id', 'url', 'display_url', 'display', 'scope_type', 'scope_id', 'scope', 'provider_network', 'port_speed', 'upstream_speed', + '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)) - def get_scope(self, obj): - if obj.scope_id is None: + def get_termination(self, obj): + if obj.termination_id is None: return None - serializer = get_serializer_for_model(obj.scope) + serializer = get_serializer_for_model(obj.termination) context = {'request': self.context['request']} - return serializer(obj.scope, nested=True, context=context).data + return serializer(obj.termination, nested=True, context=context).data class CircuitGroupSerializer(NetBoxModelSerializer): @@ -117,34 +117,34 @@ class CircuitSerializer(NetBoxModelSerializer): class CircuitTerminationSerializer(NetBoxModelSerializer, CabledObjectSerializer): circuit = CircuitSerializer(nested=True) - scope_type = ContentTypeField( + termination_type = ContentTypeField( queryset=ContentType.objects.filter( - model__in=CIRCUIT_TERMINATION_SCOPE_TYPES + model__in=CIRCUIT_TERMINATION_TERMINATION_TYPES ), allow_null=True, required=False, default=None ) - scope_id = serializers.IntegerField(allow_null=True, required=False, default=None) - scope = serializers.SerializerMethodField(read_only=True) + termination_id = serializers.IntegerField(allow_null=True, required=False, default=None) + termination = serializers.SerializerMethodField(read_only=True) provider_network = ProviderNetworkSerializer(nested=True, required=False, allow_null=True) class Meta: model = CircuitTermination fields = [ - 'id', 'url', 'display_url', 'display', 'circuit', 'term_side', 'scope_type', 'scope_id', 'scope', 'provider_network', 'port_speed', + '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') @extend_schema_field(serializers.JSONField(allow_null=True)) - def get_scope(self, obj): - if obj.scope_id is None: + def get_termination(self, obj): + if obj.termination_id is None: return None - serializer = get_serializer_for_model(obj.scope) + serializer = get_serializer_for_model(obj.termination) context = {'request': self.context['request']} - return serializer(obj.scope, nested=True, context=context).data + return serializer(obj.termination, nested=True, context=context).data class CircuitGroupAssignmentSerializer(CircuitGroupAssignmentSerializer_): diff --git a/netbox/circuits/constants.py b/netbox/circuits/constants.py index c1ee25dbc..8119bc286 100644 --- a/netbox/circuits/constants.py +++ b/netbox/circuits/constants.py @@ -1,4 +1,4 @@ -# models values for ContentTypes which may be CircuitTermination scope types -CIRCUIT_TERMINATION_SCOPE_TYPES = ( +# models values for ContentTypes which may be CircuitTermination termination types +CIRCUIT_TERMINATION_TERMINATION_TYPES = ( 'region', 'sitegroup', 'site', 'location', 'providernetwork', ) diff --git a/netbox/circuits/filtersets.py b/netbox/circuits/filtersets.py index 21b12fc94..8a485394a 100644 --- a/netbox/circuits/filtersets.py +++ b/netbox/circuits/filtersets.py @@ -263,7 +263,7 @@ class CircuitTerminationFilterSet(NetBoxModelFilterSet, CabledObjectFilterSet): queryset=Circuit.objects.all(), label=_('Circuit'), ) - scope_type = ContentTypeFilter() + termination_type = ContentTypeFilter() region_id = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='_region', @@ -334,7 +334,7 @@ class CircuitTerminationFilterSet(NetBoxModelFilterSet, CabledObjectFilterSet): class Meta: model = CircuitTermination fields = ( - 'id', 'scope_id', 'term_side', 'port_speed', 'upstream_speed', 'xconnect_id', 'description', 'mark_connected', + 'id', 'termination_id', 'term_side', 'port_speed', 'upstream_speed', 'xconnect_id', 'description', 'mark_connected', 'pp_info', 'cable_end', ) diff --git a/netbox/circuits/forms/bulk_edit.py b/netbox/circuits/forms/bulk_edit.py index 46e4570bb..0d1599ab9 100644 --- a/netbox/circuits/forms/bulk_edit.py +++ b/netbox/circuits/forms/bulk_edit.py @@ -3,7 +3,7 @@ from django.contrib.contenttypes.models import ContentType from django.utils.translation import gettext_lazy as _ from circuits.choices import CircuitCommitRateChoices, CircuitPriorityChoices, CircuitStatusChoices -from circuits.constants import CIRCUIT_TERMINATION_SCOPE_TYPES +from circuits.constants import CIRCUIT_TERMINATION_TERMINATION_TYPES from circuits.models import * from dcim.models import Site from ipam.models import ASN @@ -199,14 +199,14 @@ class CircuitTerminationBulkEditForm(NetBoxModelBulkEditForm): max_length=200, required=False ) - scope_type = ContentTypeChoiceField( - queryset=ContentType.objects.filter(model__in=CIRCUIT_TERMINATION_SCOPE_TYPES), + termination_type = ContentTypeChoiceField( + queryset=ContentType.objects.filter(model__in=CIRCUIT_TERMINATION_TERMINATION_TYPES), widget=HTMXSelect(method='post', attrs={'hx-select': '#form_fields'}), required=False, - label=_('Scope type') + label=_('Termination type') ) - scope = DynamicModelChoiceField( - label=_('Scope'), + termination = DynamicModelChoiceField( + label=_('Termination'), queryset=Site.objects.none(), # Initial queryset required=False, disabled=True, @@ -230,24 +230,24 @@ class CircuitTerminationBulkEditForm(NetBoxModelBulkEditForm): fieldsets = ( FieldSet( 'description', - 'scope_type', 'scope', + 'termination_type', 'termination', 'mark_connected', name=_('Circuit Termination') ), FieldSet('port_speed', 'upstream_speed', name=_('Termination Details')), ) - nullable_fields = ('description', 'scope') + nullable_fields = ('description', 'termination') def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - if scope_type_id := get_field_value(self, 'scope_type'): + if termination_type_id := get_field_value(self, 'termination_type'): try: - scope_type = ContentType.objects.get(pk=scope_type_id) - model = scope_type.model_class() - self.fields['scope'].queryset = model.objects.all() - self.fields['scope'].widget.attrs['selector'] = model._meta.label_lower - self.fields['scope'].disabled = False - self.fields['scope'].label = _(bettertitle(model._meta.verbose_name)) + termination_type = ContentType.objects.get(pk=termination_type_id) + model = termination_type.model_class() + self.fields['termination'].queryset = model.objects.all() + self.fields['termination'].widget.attrs['selector'] = model._meta.label_lower + self.fields['termination'].disabled = False + self.fields['termination'].label = _(bettertitle(model._meta.verbose_name)) except ObjectDoesNotExist: pass diff --git a/netbox/circuits/forms/bulk_import.py b/netbox/circuits/forms/bulk_import.py index 87b1e840e..451fe158f 100644 --- a/netbox/circuits/forms/bulk_import.py +++ b/netbox/circuits/forms/bulk_import.py @@ -128,10 +128,10 @@ class BaseCircuitTerminationImportForm(forms.ModelForm): label=_('Termination'), choices=CircuitTerminationSideChoices, ) - scope_type = CSVContentTypeField( - queryset=ContentType.objects.filter(model__in=CIRCUIT_TERMINATION_SCOPE_TYPES), + termination_type = CSVContentTypeField( + queryset=ContentType.objects.filter(model__in=CIRCUIT_TERMINATION_TERMINATION_TYPES), required=False, - label=_('Scope type (app & model)') + label=_('Termination type (app & model)') ) @@ -139,11 +139,11 @@ class CircuitTerminationImportRelatedForm(BaseCircuitTerminationImportForm): class Meta: model = CircuitTermination fields = [ - 'circuit', 'term_side', 'scope_type', 'scope_id', 'port_speed', 'upstream_speed', 'xconnect_id', + 'circuit', 'term_side', 'termination_type', 'termination_id', 'port_speed', 'upstream_speed', 'xconnect_id', 'pp_info', 'description' ] labels = { - 'scope_id': 'Scope ID', + 'termination_id': 'Termination ID', } @@ -152,11 +152,11 @@ class CircuitTerminationImportForm(NetBoxModelImportForm, BaseCircuitTermination class Meta: model = CircuitTermination fields = [ - 'circuit', 'term_side', 'scope_type', 'scope_id', 'port_speed', 'upstream_speed', 'xconnect_id', + 'circuit', 'term_side', 'termination_type', 'termination_id', 'port_speed', 'upstream_speed', 'xconnect_id', 'pp_info', 'description', 'tags' ] labels = { - 'scope_id': 'Scope ID', + 'termination_id': 'Termination ID', } diff --git a/netbox/circuits/forms/filtersets.py b/netbox/circuits/forms/filtersets.py index 1bbd4ee3b..b585ce079 100644 --- a/netbox/circuits/forms/filtersets.py +++ b/netbox/circuits/forms/filtersets.py @@ -208,7 +208,7 @@ class CircuitTerminationFilterForm(NetBoxModelFilterSetForm): FieldSet('q', 'filter_id', 'tag'), FieldSet('circuit_id', 'term_side', name=_('Circuit')), FieldSet('provider_id', name=_('Provider')), - FieldSet('region_id', 'site_group_id', 'site_id', 'location_id', name=_('Scope')), + FieldSet('region_id', 'site_group_id', 'site_id', 'location_id', name=_('Termination')), ) region_id = DynamicModelMultipleChoiceField( queryset=Region.objects.all(), diff --git a/netbox/circuits/forms/model_forms.py b/netbox/circuits/forms/model_forms.py index 7b3e38be5..10cd06563 100644 --- a/netbox/circuits/forms/model_forms.py +++ b/netbox/circuits/forms/model_forms.py @@ -149,14 +149,14 @@ class CircuitTerminationForm(NetBoxModelForm): queryset=Circuit.objects.all(), selector=True ) - scope_type = ContentTypeChoiceField( - queryset=ContentType.objects.filter(model__in=CIRCUIT_TERMINATION_SCOPE_TYPES), + termination_type = ContentTypeChoiceField( + queryset=ContentType.objects.filter(model__in=CIRCUIT_TERMINATION_TERMINATION_TYPES), widget=HTMXSelect(), required=False, - label=_('Scope type') + label=_('Termination type') ) - scope = DynamicModelChoiceField( - label=_('Scope'), + termination = DynamicModelChoiceField( + label=_('Termination'), queryset=Site.objects.none(), # Initial queryset required=False, disabled=True, @@ -166,7 +166,7 @@ class CircuitTerminationForm(NetBoxModelForm): fieldsets = ( FieldSet( 'circuit', 'term_side', 'description', 'tags', - 'scope_type', 'scope', + 'termination_type', 'termination', 'mark_connected', name=_('Circuit Termination') ), FieldSet('port_speed', 'upstream_speed', 'xconnect_id', 'pp_info', name=_('Termination Details')), @@ -175,7 +175,7 @@ class CircuitTerminationForm(NetBoxModelForm): class Meta: model = CircuitTermination fields = [ - 'circuit', 'term_side', 'scope_type', 'mark_connected', 'port_speed', 'upstream_speed', + 'circuit', 'term_side', 'termination_type', 'mark_connected', 'port_speed', 'upstream_speed', 'xconnect_id', 'pp_info', 'description', 'tags', ] widgets = { @@ -191,31 +191,31 @@ class CircuitTerminationForm(NetBoxModelForm): instance = kwargs.get('instance') initial = kwargs.get('initial', {}) - if instance is not None and instance.scope: - initial['scope'] = instance.scope + if instance is not None and instance.termination: + initial['termination'] = instance.termination kwargs['initial'] = initial super().__init__(*args, **kwargs) - if scope_type_id := get_field_value(self, 'scope_type'): + if termination_type_id := get_field_value(self, 'termination_type'): try: - scope_type = ContentType.objects.get(pk=scope_type_id) - model = scope_type.model_class() - self.fields['scope'].queryset = model.objects.all() - self.fields['scope'].widget.attrs['selector'] = model._meta.label_lower - self.fields['scope'].disabled = False - self.fields['scope'].label = _(bettertitle(model._meta.verbose_name)) + termination_type = ContentType.objects.get(pk=termination_type_id) + model = termination_type.model_class() + self.fields['termination'].queryset = model.objects.all() + self.fields['termination'].widget.attrs['selector'] = model._meta.label_lower + self.fields['termination'].disabled = False + self.fields['termination'].label = _(bettertitle(model._meta.verbose_name)) except ObjectDoesNotExist: pass - if self.instance and scope_type_id != self.instance.scope_type_id: - self.initial['scope'] = None + if self.instance and termination_type_id != self.instance.termination_type_id: + self.initial['termination'] = None def clean(self): super().clean() - # Assign the selected scope (if any) - self.instance.scope = self.cleaned_data.get('scope') + # Assign the selected termination (if any) + self.instance.termination = self.cleaned_data.get('termination') class CircuitGroupForm(TenancyForm, NetBoxModelForm): diff --git a/netbox/circuits/graphql/types.py b/netbox/circuits/graphql/types.py index fcec3c619..945e257a0 100644 --- a/netbox/circuits/graphql/types.py +++ b/netbox/circuits/graphql/types.py @@ -59,21 +59,21 @@ class ProviderNetworkType(NetBoxObjectType): @strawberry_django.type( models.CircuitTermination, - exclude=('scope_type', 'scope_id', '_location', '_region', '_site', '_sitegroup', '_provider_network'), + exclude=('termination_type', 'termination_id', '_location', '_region', '_site', '_sitegroup', '_provider_network'), filters=CircuitTerminationFilter ) class CircuitTerminationType(CustomFieldsMixin, TagsMixin, CabledObjectMixin, ObjectType): circuit: Annotated["CircuitType", strawberry.lazy('circuits.graphql.types')] @strawberry_django.field - def scope(self) -> Annotated[Union[ + def termination(self) -> Annotated[Union[ Annotated["LocationType", strawberry.lazy('dcim.graphql.types')], Annotated["RegionType", strawberry.lazy('dcim.graphql.types')], Annotated["SiteGroupType", strawberry.lazy('dcim.graphql.types')], Annotated["SiteType", strawberry.lazy('dcim.graphql.types')], Annotated["ProviderNetworkType", strawberry.lazy('circuits.graphql.types')], - ], strawberry.union("CircuitTerminationScopeType")] | None: - return self.scope + ], strawberry.union("CircuitTerminationTerminationType")] | None: + return self.termination @strawberry_django.type( diff --git a/netbox/circuits/migrations/0047_circuittermination__scope.py b/netbox/circuits/migrations/0047_circuittermination__termination.py similarity index 81% rename from netbox/circuits/migrations/0047_circuittermination__scope.py rename to netbox/circuits/migrations/0047_circuittermination__termination.py index 587a49158..cb2c9ca07 100644 --- a/netbox/circuits/migrations/0047_circuittermination__scope.py +++ b/netbox/circuits/migrations/0047_circuittermination__termination.py @@ -4,21 +4,21 @@ from django.db import migrations, models def copy_site_assignments(apps, schema_editor): """ - Copy site ForeignKey values to the scope GFK. + Copy site ForeignKey values to the Termination GFK. """ ContentType = apps.get_model('contenttypes', 'ContentType') CircuitTermination = apps.get_model('circuits', 'CircuitTermination') Site = apps.get_model('dcim', 'Site') CircuitTermination.objects.filter(site__isnull=False).update( - scope_type=ContentType.objects.get_for_model(Site), - scope_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( - scope_type=ContentType.objects.get_for_model(ProviderNetwork), - scope_id=models.F('provider_network_id') + termination_type=ContentType.objects.get_for_model(ProviderNetwork), + termination_id=models.F('provider_network_id') ) class Migration(migrations.Migration): @@ -32,12 +32,12 @@ class Migration(migrations.Migration): operations = [ migrations.AddField( model_name='circuittermination', - name='scope_id', + name='termination_id', field=models.PositiveBigIntegerField(blank=True, null=True), ), migrations.AddField( model_name='circuittermination', - name='scope_type', + name='termination_type', field=models.ForeignKey( blank=True, limit_choices_to=models.Q(('model__in', ('region', 'sitegroup', 'site', 'location', 'providernetwork'))), diff --git a/netbox/circuits/migrations/0048_circuitterminations_cached_relations.py b/netbox/circuits/migrations/0048_circuitterminations_cached_relations.py index aa9e55d02..2d379b97a 100644 --- a/netbox/circuits/migrations/0048_circuitterminations_cached_relations.py +++ b/netbox/circuits/migrations/0048_circuitterminations_cached_relations.py @@ -5,7 +5,7 @@ from django.db import migrations, models def populate_denormalized_fields(apps, schema_editor): """ - Copy site ForeignKey values to the scope GFK. + Copy site ForeignKey values to the Termination GFK. """ CircuitTermination = apps.get_model('circuits', 'CircuitTermination') @@ -22,7 +22,7 @@ def populate_denormalized_fields(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('circuits', '0047_circuittermination__scope'), + ('circuits', '0047_circuittermination__termination'), ] operations = [ @@ -33,7 +33,7 @@ class Migration(migrations.Migration): blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, - related_name='_circuit_terminations', + related_name='circuit_terminations', to='dcim.location', ), ), @@ -44,7 +44,7 @@ class Migration(migrations.Migration): blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, - related_name='_circuit_terminations', + related_name='circuit_terminations', to='dcim.region', ), ), @@ -55,7 +55,7 @@ class Migration(migrations.Migration): blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, - related_name='_circuit_terminations', + related_name='circuit_terminations', to='dcim.site', ), ), @@ -66,7 +66,7 @@ class Migration(migrations.Migration): blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, - related_name='_circuit_terminations', + related_name='circuit_terminations', to='dcim.sitegroup', ), ), diff --git a/netbox/circuits/models/circuits.py b/netbox/circuits/models/circuits.py index c90c0bd8a..d9e338636 100644 --- a/netbox/circuits/models/circuits.py +++ b/netbox/circuits/models/circuits.py @@ -236,21 +236,21 @@ class CircuitTermination( choices=CircuitTerminationSideChoices, verbose_name=_('termination') ) - scope_type = models.ForeignKey( + termination_type = models.ForeignKey( to='contenttypes.ContentType', on_delete=models.PROTECT, - limit_choices_to=Q(model__in=CIRCUIT_TERMINATION_SCOPE_TYPES), + limit_choices_to=Q(model__in=CIRCUIT_TERMINATION_TERMINATION_TYPES), related_name='+', blank=True, null=True ) - scope_id = models.PositiveBigIntegerField( + termination_id = models.PositiveBigIntegerField( blank=True, null=True ) - scope = GenericForeignKey( - ct_field='scope_type', - fk_field='scope_id' + termination = GenericForeignKey( + ct_field='termination_type', + fk_field='termination_id' ) port_speed = models.PositiveIntegerField( verbose_name=_('port speed (Kbps)'), @@ -293,28 +293,28 @@ class CircuitTermination( _location = models.ForeignKey( to='dcim.Location', on_delete=models.CASCADE, - related_name='_circuit_terminations', + related_name='circuit_terminations', blank=True, null=True ) _site = models.ForeignKey( to='dcim.Site', on_delete=models.CASCADE, - related_name='_circuit_terminations', + related_name='circuit_terminations', blank=True, null=True ) _region = models.ForeignKey( to='dcim.Region', on_delete=models.CASCADE, - related_name='_circuit_terminations', + related_name='circuit_terminations', blank=True, null=True ) _sitegroup = models.ForeignKey( to='dcim.SiteGroup', on_delete=models.CASCADE, - related_name='_circuit_terminations', + related_name='circuit_terminations', blank=True, null=True ) @@ -340,8 +340,8 @@ class CircuitTermination( super().clean() # Must define either site *or* provider network - if self.scope is None: - raise ValidationError(_("A circuit termination must attach to either a scope or a provider network.")) + if self.termination is None: + raise ValidationError(_("A circuit termination must attach to termination.")) def save(self, *args, **kwargs): # Cache objects associated with the terminating object (for filtering) @@ -351,23 +351,23 @@ class CircuitTermination( def cache_related_objects(self): self._provider_network = self._region = self._sitegroup = self._site = self._location = None - if self.scope_type: - scope_type = self.scope_type.model_class() - if scope_type == apps.get_model('dcim', 'region'): - self._region = self.scope - elif scope_type == apps.get_model('dcim', 'sitegroup'): - self._sitegroup = self.scope - elif scope_type == apps.get_model('dcim', 'site'): - self._region = self.scope.region - self._sitegroup = self.scope.group - self._site = self.scope - elif scope_type == apps.get_model('dcim', 'location'): - self._region = self.scope.site.region - self._sitegroup = self.scope.site.group - self._site = self.scope.site - self._location = self.scope - elif scope_type == apps.get_model('circuits', 'providernetwork'): - self._provider_network = self.scope + if self.termination_type: + termination_type = self.termination_type.model_class() + if termination_type == apps.get_model('dcim', 'region'): + self._region = self.termination + elif termination_type == apps.get_model('dcim', 'sitegroup'): + self._sitegroup = self.termination + elif termination_type == apps.get_model('dcim', 'site'): + self._region = self.termination.region + self._sitegroup = self.termination.group + self._site = self.termination + elif termination_type == apps.get_model('dcim', 'location'): + self._region = self.termination.site.region + self._sitegroup = self.termination.site.group + self._site = self.termination.site + self._location = self.termination + elif termination_type == apps.get_model('circuits', 'providernetwork'): + self._provider_network = self.termination cache_related_objects.alters_data = True def to_objectchange(self, action): @@ -382,7 +382,7 @@ class CircuitTermination( def get_peer_termination(self): peer_side = 'Z' if self.term_side == 'A' else 'A' try: - return CircuitTermination.objects.prefetch_related('scope').get( + return CircuitTermination.objects.prefetch_related('termination').get( circuit=self.circuit, term_side=peer_side ) diff --git a/netbox/circuits/tests/test_api.py b/netbox/circuits/tests/test_api.py index 008ed3324..1b2e9f3f8 100644 --- a/netbox/circuits/tests/test_api.py +++ b/netbox/circuits/tests/test_api.py @@ -181,10 +181,10 @@ class CircuitTerminationTest(APIViewTestCases.APIViewTestCase): Circuit.objects.bulk_create(circuits) circuit_terminations = ( - CircuitTermination(circuit=circuits[0], term_side=SIDE_A, scope=sites[0]), - CircuitTermination(circuit=circuits[0], term_side=SIDE_Z, scope=provider_networks[0]), - CircuitTermination(circuit=circuits[1], term_side=SIDE_A, scope=sites[1]), - CircuitTermination(circuit=circuits[1], term_side=SIDE_Z, scope=provider_networks[1]), + CircuitTermination(circuit=circuits[0], term_side=SIDE_A, termination=sites[0]), + CircuitTermination(circuit=circuits[0], term_side=SIDE_Z, termination=provider_networks[0]), + CircuitTermination(circuit=circuits[1], term_side=SIDE_A, termination=sites[1]), + CircuitTermination(circuit=circuits[1], term_side=SIDE_Z, termination=provider_networks[1]), ) CircuitTermination.objects.bulk_create(circuit_terminations) @@ -192,15 +192,15 @@ class CircuitTerminationTest(APIViewTestCases.APIViewTestCase): { 'circuit': circuits[2].pk, 'term_side': SIDE_A, - 'scope_type': 'dcim.site', - 'scope_id': sites[0].pk, + 'termination_type': 'dcim.site', + 'termination_id': sites[0].pk, 'port_speed': 200000, }, { 'circuit': circuits[2].pk, 'term_side': SIDE_Z, - 'scope_type': 'circuits.providernetwork', - 'scope_id': provider_networks[0].pk, + 'termination_type': 'circuits.providernetwork', + 'termination_id': provider_networks[0].pk, 'port_speed': 200000, }, ] diff --git a/netbox/circuits/tests/test_filtersets.py b/netbox/circuits/tests/test_filtersets.py index 4e4f2d34c..0dbc7172b 100644 --- a/netbox/circuits/tests/test_filtersets.py +++ b/netbox/circuits/tests/test_filtersets.py @@ -71,8 +71,8 @@ class ProviderTestCase(TestCase, ChangeLoggedFilterSetTests): Circuit.objects.bulk_create(circuits) circuit_terminations = ( - CircuitTermination(circuit=circuits[0], scope=sites[0], term_side='A'), - CircuitTermination(circuit=circuits[1], scope=sites[0], term_side='A'), + CircuitTermination(circuit=circuits[0], termination=sites[0], term_side='A'), + CircuitTermination(circuit=circuits[1], termination=sites[0], term_side='A'), ) for ct in circuit_terminations: ct.save() @@ -235,12 +235,12 @@ class CircuitTestCase(TestCase, ChangeLoggedFilterSetTests): Circuit.objects.bulk_create(circuits) circuit_terminations = (( - CircuitTermination(circuit=circuits[0], scope=sites[0], term_side='A'), - CircuitTermination(circuit=circuits[1], scope=sites[1], term_side='A'), - CircuitTermination(circuit=circuits[2], scope=sites[2], term_side='A'), - CircuitTermination(circuit=circuits[3], scope=provider_networks[0], term_side='A'), - CircuitTermination(circuit=circuits[4], scope=provider_networks[1], term_side='A'), - CircuitTermination(circuit=circuits[5], scope=provider_networks[2], term_side='A'), + CircuitTermination(circuit=circuits[0], termination=sites[0], term_side='A'), + CircuitTermination(circuit=circuits[1], termination=sites[1], term_side='A'), + CircuitTermination(circuit=circuits[2], termination=sites[2], term_side='A'), + 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'), )) for ct in circuit_terminations: ct.save() @@ -387,16 +387,16 @@ class CircuitTerminationTestCase(TestCase, ChangeLoggedFilterSetTests): Circuit.objects.bulk_create(circuits) circuit_terminations = (( - CircuitTermination(circuit=circuits[0], scope=sites[0], term_side='A', port_speed=1000, upstream_speed=1000, xconnect_id='ABC', description='foobar1'), - CircuitTermination(circuit=circuits[0], scope=sites[1], term_side='Z', port_speed=1000, upstream_speed=1000, xconnect_id='DEF', description='foobar2'), - CircuitTermination(circuit=circuits[1], scope=sites[1], term_side='A', port_speed=2000, upstream_speed=2000, xconnect_id='GHI'), - CircuitTermination(circuit=circuits[1], scope=sites[2], term_side='Z', port_speed=2000, upstream_speed=2000, xconnect_id='JKL'), - CircuitTermination(circuit=circuits[2], scope=sites[2], term_side='A', port_speed=3000, upstream_speed=3000, xconnect_id='MNO'), - CircuitTermination(circuit=circuits[2], scope=sites[0], term_side='Z', port_speed=3000, upstream_speed=3000, xconnect_id='PQR'), - CircuitTermination(circuit=circuits[3], scope=provider_networks[0], term_side='A'), - CircuitTermination(circuit=circuits[4], scope=provider_networks[1], term_side='A'), - CircuitTermination(circuit=circuits[5], scope=provider_networks[2], term_side='A'), - CircuitTermination(circuit=circuits[6], scope=provider_networks[0], term_side='A', mark_connected=True), + 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), )) for ct in circuit_terminations: ct.save() diff --git a/netbox/circuits/tests/test_views.py b/netbox/circuits/tests/test_views.py index 2438c73a1..9674db4d9 100644 --- a/netbox/circuits/tests/test_views.py +++ b/netbox/circuits/tests/test_views.py @@ -203,23 +203,23 @@ class CircuitTestCase(ViewTestCases.PrimaryObjectViewTestCase): "terminations": [ { "term_side": "A", - "scope_type": "dcim.site", - "scope_id": "1" + "termination_type": "dcim.site", + "termination_id": "1" }, { "term_side": "Z", - "scope_type": "dcim.site", - "scope_id": "1" + "termination_type": "dcim.site", + "termination_id": "1" } ] } ] """ - # Fix up the scope site id + # Fix up the termination site id site = Site.objects.first() data = json.loads(json_data) - data[0]["terminations"][0]["scope_id"] = data[0]["terminations"][1]["scope_id"] = site.id + data[0]["terminations"][0]["termination_id"] = data[0]["terminations"][1]["termination_id"] = site.id json_data = json.dumps(data) initial_count = self._get_queryset().count() @@ -370,10 +370,10 @@ class TestCase(ViewTestCases.PrimaryObjectViewTestCase): Circuit.objects.bulk_create(circuits) circuit_terminations = ( - CircuitTermination(circuit=circuits[0], term_side='A', scope=sites[0]), - CircuitTermination(circuit=circuits[0], term_side='Z', scope=sites[1]), - CircuitTermination(circuit=circuits[1], term_side='A', scope=sites[0]), - CircuitTermination(circuit=circuits[1], term_side='Z', scope=sites[1]), + CircuitTermination(circuit=circuits[0], term_side='A', termination=sites[0]), + CircuitTermination(circuit=circuits[0], term_side='Z', termination=sites[1]), + CircuitTermination(circuit=circuits[1], term_side='A', termination=sites[0]), + CircuitTermination(circuit=circuits[1], term_side='Z', termination=sites[1]), ) for ct in circuit_terminations: ct.save() @@ -381,14 +381,14 @@ class TestCase(ViewTestCases.PrimaryObjectViewTestCase): cls.form_data = { 'circuit': circuits[2].pk, 'term_side': 'A', - 'scope_type': ContentType.objects.get_for_model(Site).pk, - 'scope': sites[2].pk, + 'termination_type': ContentType.objects.get_for_model(Site).pk, + 'termination': sites[2].pk, 'description': 'New description', } site = sites[0].pk cls.csv_data = ( - "circuit,term_side,scope_type,scope_id,description", + "circuit,term_side,termination_type,termination_id,description", f"Circuit 3,A,dcim.site,{site},Foo", f"Circuit 3,Z,dcim.site,{site},Bar", ) diff --git a/netbox/dcim/tests/test_cablepaths.py b/netbox/dcim/tests/test_cablepaths.py index 985030725..b504d389a 100644 --- a/netbox/dcim/tests/test_cablepaths.py +++ b/netbox/dcim/tests/test_cablepaths.py @@ -1167,7 +1167,7 @@ class CablePathTestCase(TestCase): [IF1] --C1-- [CT1] """ interface1 = Interface.objects.create(device=self.device, name='Interface 1') - circuittermination1 = CircuitTermination.objects.create(circuit=self.circuit, scope=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 +1198,7 @@ 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, scope=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 +1214,7 @@ class CablePathTestCase(TestCase): ) # Create CT2 - circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, scope=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 +1266,7 @@ 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, scope=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 +1282,7 @@ class CablePathTestCase(TestCase): ) # Create CT2 - circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, scope=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( @@ -1335,8 +1335,8 @@ 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, scope=self.site, term_side='A') - circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, scope=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 +1365,8 @@ 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, scope=self.site, term_side='A') - circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, scope=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 +1413,8 @@ 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, scope=self.site, term_side='A') - circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, scope=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 +1499,10 @@ 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, scope=self.site, term_side='A') - circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, scope=self.site, term_side='Z') - circuittermination3 = CircuitTermination.objects.create(circuit=circuit2, scope=self.site, term_side='A') - circuittermination4 = CircuitTermination.objects.create(circuit=circuit2, scope=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( diff --git a/netbox/dcim/tests/test_filtersets.py b/netbox/dcim/tests/test_filtersets.py index 55ec967d2..d65adb8c9 100644 --- a/netbox/dcim/tests/test_filtersets.py +++ b/netbox/dcim/tests/test_filtersets.py @@ -5117,7 +5117,7 @@ class CableTestCase(TestCase, ChangeLoggedFilterSetTests): provider = Provider.objects.create(name='Provider 1', slug='provider-1') circuit_type = CircuitType.objects.create(name='Circuit Type 1', slug='circuit-type-1') circuit = Circuit.objects.create(cid='Circuit 1', provider=provider, type=circuit_type) - circuit_termination = CircuitTermination.objects.create(circuit=circuit, term_side='A', scope=sites[0]) + circuit_termination = CircuitTermination.objects.create(circuit=circuit, term_side='A', termination=sites[0]) # Cables cables = ( diff --git a/netbox/dcim/tests/test_models.py b/netbox/dcim/tests/test_models.py index 4886bb255..f0fe4da3b 100644 --- a/netbox/dcim/tests/test_models.py +++ b/netbox/dcim/tests/test_models.py @@ -762,9 +762,9 @@ class CableTestCase(TestCase): circuittype = CircuitType.objects.create(name='Circuit Type 1', slug='circuit-type-1') circuit1 = Circuit.objects.create(provider=provider, type=circuittype, cid='1') circuit2 = Circuit.objects.create(provider=provider, type=circuittype, cid='2') - CircuitTermination.objects.create(circuit=circuit1, scope=site, term_side='A') - CircuitTermination.objects.create(circuit=circuit1, scope=site, term_side='Z') - CircuitTermination.objects.create(circuit=circuit2, scope=provider_network, term_side='A') + CircuitTermination.objects.create(circuit=circuit1, termination=site, term_side='A') + CircuitTermination.objects.create(circuit=circuit1, termination=site, term_side='Z') + CircuitTermination.objects.create(circuit=circuit2, termination=provider_network, term_side='A') def test_cable_creation(self): """ diff --git a/netbox/templates/circuits/inc/circuit_termination_fields.html b/netbox/templates/circuits/inc/circuit_termination_fields.html index a90a4b8e4..0157b98cc 100644 --- a/netbox/templates/circuits/inc/circuit_termination_fields.html +++ b/netbox/templates/circuits/inc/circuit_termination_fields.html @@ -1,11 +1,11 @@ {% load helpers %} {% load i18n %} -{% if termination.scope %} +{% if termination.termination %} - {% trans "Scope" %} - {% if termination.scope %} - {{ termination.scope|linkify }} ({% trans termination.scope_type.name %}) + {% trans "Termination" %} + {% if termination.termination %} + {{ termination.termination|linkify }} ({% trans termination.termination_type.name %}) {% else %} {{ ''|placeholder }} {% endif %}