From 8e9e1e9e64028916f37497b3b697476de80574d6 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 22 Nov 2023 15:10:23 -0500 Subject: [PATCH] Move L2VPN and L2VPNTermination models from ipam to vpn --- netbox/dcim/filtersets.py | 3 +- netbox/dcim/forms/filtersets.py | 3 +- netbox/dcim/models/device_components.py | 2 +- netbox/ipam/api/nested_serializers.py | 2 +- netbox/ipam/api/serializers.py | 1 + netbox/ipam/api/views.py | 2 +- netbox/ipam/filtersets.py | 1 + netbox/ipam/forms/bulk_edit.py | 1 + netbox/ipam/forms/bulk_import.py | 1 + netbox/ipam/forms/filtersets.py | 1 + netbox/ipam/forms/model_forms.py | 1 + netbox/ipam/graphql/schema.py | 9 ++- netbox/ipam/graphql/types.py | 5 +- netbox/ipam/migrations/0068_move_l2vpn.py | 47 ++++++++++++ netbox/ipam/models/__init__.py | 22 ------ netbox/ipam/models/vlans.py | 3 +- netbox/ipam/search.py | 5 +- netbox/ipam/tables/l2vpn.py | 2 +- netbox/ipam/tests/test_api.py | 1 + netbox/ipam/tests/test_filtersets.py | 1 + netbox/ipam/tests/test_models.py | 5 +- netbox/ipam/tests/test_views.py | 1 + netbox/ipam/views.py | 3 +- netbox/virtualization/forms/filtersets.py | 3 +- .../virtualization/models/virtualmachines.py | 2 +- netbox/vpn/migrations/0002_move_l2vpn.py | 73 +++++++++++++++++++ netbox/vpn/models/__init__.py | 1 + netbox/{ipam => vpn}/models/l2vpn.py | 10 +-- 28 files changed, 163 insertions(+), 48 deletions(-) create mode 100644 netbox/ipam/migrations/0068_move_l2vpn.py create mode 100644 netbox/vpn/migrations/0002_move_l2vpn.py rename netbox/{ipam => vpn}/models/l2vpn.py (95%) diff --git a/netbox/dcim/filtersets.py b/netbox/dcim/filtersets.py index ffd3879a8..36540f3e3 100644 --- a/netbox/dcim/filtersets.py +++ b/netbox/dcim/filtersets.py @@ -5,7 +5,7 @@ from django.utils.translation import gettext as _ from extras.filtersets import LocalConfigContextFilterSet from extras.models import ConfigTemplate from ipam.filtersets import PrimaryIPFilterSet -from ipam.models import ASN, L2VPN, IPAddress, VRF +from ipam.models import ASN, IPAddress, VRF from netbox.filtersets import ( BaseFilterSet, ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, NetBoxModelFilterSet, ) @@ -17,6 +17,7 @@ from utilities.filters import ( TreeNodeMultipleChoiceFilter, ) from virtualization.models import Cluster +from vpn.models import L2VPN from wireless.choices import WirelessRoleChoices, WirelessChannelChoices from .choices import * from .constants import * diff --git a/netbox/dcim/forms/filtersets.py b/netbox/dcim/forms/filtersets.py index d0d321187..1c8713a28 100644 --- a/netbox/dcim/forms/filtersets.py +++ b/netbox/dcim/forms/filtersets.py @@ -7,12 +7,13 @@ from dcim.constants import * from dcim.models import * from extras.forms import LocalConfigContextFilterForm from extras.models import ConfigTemplate -from ipam.models import ASN, L2VPN, VRF +from ipam.models import ASN, VRF from netbox.forms import NetBoxModelFilterSetForm from tenancy.forms import ContactModelFilterForm, TenancyFilterForm from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES, FilterForm, add_blank_choice from utilities.forms.fields import ColorField, DynamicModelMultipleChoiceField, TagFilterField from utilities.forms.widgets import APISelectMultiple, NumberWithOptions +from vpn.models import L2VPN from wireless.choices import * __all__ = ( diff --git a/netbox/dcim/models/device_components.py b/netbox/dcim/models/device_components.py index 705af7637..94ae2d6a6 100644 --- a/netbox/dcim/models/device_components.py +++ b/netbox/dcim/models/device_components.py @@ -730,7 +730,7 @@ class Interface(ModularComponentModel, BaseInterface, CabledObjectModel, PathEnd related_query_name='interface' ) l2vpn_terminations = GenericRelation( - to='ipam.L2VPNTermination', + to='vpn.L2VPNTermination', content_type_field='assigned_object_type', object_id_field='assigned_object_id', related_query_name='interface', diff --git a/netbox/ipam/api/nested_serializers.py b/netbox/ipam/api/nested_serializers.py index 9e150e2cb..cca2c017b 100644 --- a/netbox/ipam/api/nested_serializers.py +++ b/netbox/ipam/api/nested_serializers.py @@ -2,8 +2,8 @@ from drf_spectacular.utils import extend_schema_serializer from rest_framework import serializers from ipam import models -from ipam.models.l2vpn import L2VPNTermination, L2VPN from netbox.api.serializers import WritableNestedSerializer +from vpn.models import L2VPN, L2VPNTermination from .field_serializers import IPAddressField __all__ = [ diff --git a/netbox/ipam/api/serializers.py b/netbox/ipam/api/serializers.py index 6882de56d..f2afbc8c4 100644 --- a/netbox/ipam/api/serializers.py +++ b/netbox/ipam/api/serializers.py @@ -12,6 +12,7 @@ from netbox.constants import NESTED_SERIALIZER_PREFIX from tenancy.api.nested_serializers import NestedTenantSerializer from utilities.api import get_serializer_for_model from virtualization.api.nested_serializers import NestedVirtualMachineSerializer +from vpn.models import L2VPN, L2VPNTermination from .nested_serializers import * from .field_serializers import IPAddressField, IPNetworkField diff --git a/netbox/ipam/api/views.py b/netbox/ipam/api/views.py index 662b393de..5b474a1e9 100644 --- a/netbox/ipam/api/views.py +++ b/netbox/ipam/api/views.py @@ -14,7 +14,6 @@ from circuits.models import Provider from dcim.models import Site from ipam import filtersets from ipam.models import * -from ipam.models import L2VPN, L2VPNTermination from ipam.utils import get_next_available_prefix from netbox.api.viewsets import NetBoxModelViewSet from netbox.api.viewsets.mixins import ObjectValidationMixin @@ -22,6 +21,7 @@ from netbox.config import get_config from netbox.constants import ADVISORY_LOCK_KEYS from utilities.api import get_serializer_for_model from utilities.utils import count_related +from vpn.models import L2VPN, L2VPNTermination from . import serializers diff --git a/netbox/ipam/filtersets.py b/netbox/ipam/filtersets.py index ba944e3ad..1e4a4f526 100644 --- a/netbox/ipam/filtersets.py +++ b/netbox/ipam/filtersets.py @@ -15,6 +15,7 @@ from utilities.filters import ( ContentTypeFilter, MultiValueCharFilter, MultiValueNumberFilter, NumericArrayFilter, TreeNodeMultipleChoiceFilter, ) from virtualization.models import VirtualMachine, VMInterface +from vpn.models import L2VPN, L2VPNTermination from .choices import * from .models import * diff --git a/netbox/ipam/forms/bulk_edit.py b/netbox/ipam/forms/bulk_edit.py index f0a8286fc..b048dd9d4 100644 --- a/netbox/ipam/forms/bulk_edit.py +++ b/netbox/ipam/forms/bulk_edit.py @@ -15,6 +15,7 @@ from utilities.forms.fields import ( ) from utilities.forms.widgets import BulkEditNullBooleanSelect from virtualization.models import Cluster, ClusterGroup +from vpn.models import L2VPN __all__ = ( 'AggregateBulkEditForm', diff --git a/netbox/ipam/forms/bulk_import.py b/netbox/ipam/forms/bulk_import.py index ed3ceec2b..ae5248ae2 100644 --- a/netbox/ipam/forms/bulk_import.py +++ b/netbox/ipam/forms/bulk_import.py @@ -13,6 +13,7 @@ from utilities.forms.fields import ( CSVChoiceField, CSVContentTypeField, CSVModelChoiceField, CSVModelMultipleChoiceField, SlugField ) from virtualization.models import VirtualMachine, VMInterface +from vpn.models import L2VPN, L2VPNTermination __all__ = ( 'AggregateImportForm', diff --git a/netbox/ipam/forms/filtersets.py b/netbox/ipam/forms/filtersets.py index a8ca91901..ae1fd581d 100644 --- a/netbox/ipam/forms/filtersets.py +++ b/netbox/ipam/forms/filtersets.py @@ -13,6 +13,7 @@ from utilities.forms.fields import ( ContentTypeMultipleChoiceField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, TagFilterField, ) from virtualization.models import VirtualMachine +from vpn.models import L2VPN, L2VPNTermination __all__ = ( 'AggregateFilterForm', diff --git a/netbox/ipam/forms/model_forms.py b/netbox/ipam/forms/model_forms.py index dd9e6b3e4..1b75f3b5d 100644 --- a/netbox/ipam/forms/model_forms.py +++ b/netbox/ipam/forms/model_forms.py @@ -18,6 +18,7 @@ from utilities.forms.fields import ( ) from utilities.forms.widgets import DatePicker from virtualization.models import Cluster, ClusterGroup, VirtualMachine, VMInterface +from vpn.models import L2VPN, L2VPNTermination __all__ = ( 'AggregateForm', diff --git a/netbox/ipam/graphql/schema.py b/netbox/ipam/graphql/schema.py index 596b5eb78..875955c63 100644 --- a/netbox/ipam/graphql/schema.py +++ b/netbox/ipam/graphql/schema.py @@ -1,8 +1,9 @@ import graphene -from ipam import models -from utilities.graphql_optimizer import gql_query_optimizer +from ipam import models from netbox.graphql.fields import ObjectField, ObjectListField +from utilities.graphql_optimizer import gql_query_optimizer +from vpn.models import L2VPN, L2VPNTermination from .types import * @@ -42,13 +43,13 @@ class IPAMQuery(graphene.ObjectType): l2vpn_list = ObjectListField(L2VPNType) def resolve_l2vpn_list(root, info, **kwargs): - return gql_query_optimizer(models.L2VPN.objects.all(), info) + return gql_query_optimizer(L2VPN.objects.all(), info) l2vpn_termination = ObjectField(L2VPNTerminationType) l2vpn_termination_list = ObjectListField(L2VPNTerminationType) def resolve_l2vpn_termination_list(root, info, **kwargs): - return gql_query_optimizer(models.L2VPNTermination.objects.all(), info) + return gql_query_optimizer(L2VPNTermination.objects.all(), info) prefix = ObjectField(PrefixType) prefix_list = ObjectListField(PrefixType) diff --git a/netbox/ipam/graphql/types.py b/netbox/ipam/graphql/types.py index 6e834512e..6a61d2d1a 100644 --- a/netbox/ipam/graphql/types.py +++ b/netbox/ipam/graphql/types.py @@ -4,6 +4,7 @@ from extras.graphql.mixins import ContactsMixin from ipam import filtersets, models from netbox.graphql.scalars import BigInt from netbox.graphql.types import BaseObjectType, OrganizationalObjectType, NetBoxObjectType +from vpn.models import L2VPN, L2VPNTermination __all__ = ( 'ASNType', @@ -192,7 +193,7 @@ class VRFType(NetBoxObjectType): class L2VPNType(ContactsMixin, NetBoxObjectType): class Meta: - model = models.L2VPN + model = L2VPN fields = '__all__' filtersets_class = filtersets.L2VPNFilterSet @@ -201,6 +202,6 @@ class L2VPNTerminationType(NetBoxObjectType): assigned_object = graphene.Field('ipam.graphql.gfk_mixins.L2VPNAssignmentType') class Meta: - model = models.L2VPNTermination + model = L2VPNTermination exclude = ('assigned_object_type', 'assigned_object_id') filtersets_class = filtersets.L2VPNTerminationFilterSet diff --git a/netbox/ipam/migrations/0068_move_l2vpn.py b/netbox/ipam/migrations/0068_move_l2vpn.py new file mode 100644 index 000000000..292096f36 --- /dev/null +++ b/netbox/ipam/migrations/0068_move_l2vpn.py @@ -0,0 +1,47 @@ +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0067_ipaddress_index_host'), + ] + + operations = [ + migrations.RemoveConstraint( + model_name='l2vpntermination', + name='ipam_l2vpntermination_assigned_object', + ), + migrations.SeparateDatabaseAndState( + state_operations=[ + migrations.RemoveField( + model_name='l2vpntermination', + name='assigned_object_type', + ), + migrations.RemoveField( + model_name='l2vpntermination', + name='l2vpn', + ), + migrations.RemoveField( + model_name='l2vpntermination', + name='tags', + ), + migrations.DeleteModel( + name='L2VPN', + ), + migrations.DeleteModel( + name='L2VPNTermination', + ), + ], + database_operations=[ + migrations.AlterModelTable( + name='L2VPN', + table='vpn_l2vpn', + ), + migrations.AlterModelTable( + name='L2VPNTermination', + table='vpn_l2vpntermination', + ), + ], + ), + ] diff --git a/netbox/ipam/models/__init__.py b/netbox/ipam/models/__init__.py index a00919ee0..0d0b3d6ac 100644 --- a/netbox/ipam/models/__init__.py +++ b/netbox/ipam/models/__init__.py @@ -3,27 +3,5 @@ from .asns import * from .fhrp import * from .vrfs import * from .ip import * -from .l2vpn import * from .services import * from .vlans import * - -__all__ = ( - 'ASN', - 'ASNRange', - 'Aggregate', - 'IPAddress', - 'IPRange', - 'FHRPGroup', - 'FHRPGroupAssignment', - 'L2VPN', - 'L2VPNTermination', - 'Prefix', - 'RIR', - 'Role', - 'RouteTarget', - 'Service', - 'ServiceTemplate', - 'VLAN', - 'VLANGroup', - 'VRF', -) diff --git a/netbox/ipam/models/vlans.py b/netbox/ipam/models/vlans.py index b6aed5398..1327a6e9d 100644 --- a/netbox/ipam/models/vlans.py +++ b/netbox/ipam/models/vlans.py @@ -183,9 +183,8 @@ class VLAN(PrimaryModel): null=True, help_text=_("The primary function of this VLAN") ) - l2vpn_terminations = GenericRelation( - to='ipam.L2VPNTermination', + to='vpn.L2VPNTermination', content_type_field='assigned_object_type', object_id_field='assigned_object_id', related_query_name='vlan' diff --git a/netbox/ipam/search.py b/netbox/ipam/search.py index c08acce1b..db968f006 100644 --- a/netbox/ipam/search.py +++ b/netbox/ipam/search.py @@ -1,5 +1,6 @@ -from . import models from netbox.search import SearchIndex, register_search +from vpn.models import L2VPN +from . import models @register_search @@ -71,7 +72,7 @@ class IPRangeIndex(SearchIndex): @register_search class L2VPNIndex(SearchIndex): - model = models.L2VPN + model = L2VPN fields = ( ('name', 100), ('slug', 110), diff --git a/netbox/ipam/tables/l2vpn.py b/netbox/ipam/tables/l2vpn.py index 8635ab62a..a812fbc09 100644 --- a/netbox/ipam/tables/l2vpn.py +++ b/netbox/ipam/tables/l2vpn.py @@ -1,9 +1,9 @@ from django.utils.translation import gettext_lazy as _ import django_tables2 as tables -from ipam.models import L2VPN, L2VPNTermination from netbox.tables import NetBoxTable, columns from tenancy.tables import TenancyColumnsMixin +from vpn.models import L2VPN, L2VPNTermination __all__ = ( 'L2VPNTable', diff --git a/netbox/ipam/tests/test_api.py b/netbox/ipam/tests/test_api.py index d696c8dae..f6b415b7a 100644 --- a/netbox/ipam/tests/test_api.py +++ b/netbox/ipam/tests/test_api.py @@ -9,6 +9,7 @@ from ipam.choices import * from ipam.models import * from tenancy.models import Tenant from utilities.testing import APITestCase, APIViewTestCases, create_test_device, disable_warnings +from vpn.models import L2VPN, L2VPNTermination class AppTest(APITestCase): diff --git a/netbox/ipam/tests/test_filtersets.py b/netbox/ipam/tests/test_filtersets.py index 952376056..5d65c2135 100644 --- a/netbox/ipam/tests/test_filtersets.py +++ b/netbox/ipam/tests/test_filtersets.py @@ -10,6 +10,7 @@ from ipam.models import * from utilities.testing import ChangeLoggedFilterSetTests, create_test_device, create_test_virtualmachine from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface from tenancy.models import Tenant, TenantGroup +from vpn.models import L2VPN, L2VPNTermination class ASNRangeTestCase(TestCase, ChangeLoggedFilterSetTests): diff --git a/netbox/ipam/tests/test_models.py b/netbox/ipam/tests/test_models.py index 06cd9b445..8c849c6ea 100644 --- a/netbox/ipam/tests/test_models.py +++ b/netbox/ipam/tests/test_models.py @@ -3,8 +3,9 @@ from django.core.exceptions import ValidationError from django.test import TestCase, override_settings from dcim.models import Interface, Device, DeviceRole, DeviceType, Manufacturer, Site -from ipam.choices import IPAddressRoleChoices, PrefixStatusChoices -from ipam.models import Aggregate, IPAddress, IPRange, Prefix, RIR, VLAN, VLANGroup, VRF, L2VPN, L2VPNTermination +from ipam.choices import * +from ipam.models import * +from vpn.models import L2VPN, L2VPNTermination class TestAggregate(TestCase): diff --git a/netbox/ipam/tests/test_views.py b/netbox/ipam/tests/test_views.py index a37584f0f..343699070 100644 --- a/netbox/ipam/tests/test_views.py +++ b/netbox/ipam/tests/test_views.py @@ -10,6 +10,7 @@ from ipam.choices import * from ipam.models import * from tenancy.models import Tenant from utilities.testing import ViewTestCases, create_test_device, create_tags +from vpn.models import L2VPN, L2VPNTermination class ASNRangeTestCase(ViewTestCases.PrimaryObjectViewTestCase): diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index 48ea637d9..970ba25f8 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -1,5 +1,5 @@ from django.contrib.contenttypes.models import ContentType -from django.db.models import F, Prefetch +from django.db.models import Prefetch from django.db.models.expressions import RawSQL from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse @@ -15,6 +15,7 @@ from utilities.utils import count_related from utilities.views import ViewTab, register_model_view from virtualization.filtersets import VMInterfaceFilterSet from virtualization.models import VMInterface +from vpn.models import L2VPN, L2VPNTermination from . import filtersets, forms, tables from .choices import PrefixStatusChoices from .constants import * diff --git a/netbox/virtualization/forms/filtersets.py b/netbox/virtualization/forms/filtersets.py index 5eb3fea1c..ba0c4cc6d 100644 --- a/netbox/virtualization/forms/filtersets.py +++ b/netbox/virtualization/forms/filtersets.py @@ -4,13 +4,14 @@ from django.utils.translation import gettext_lazy as _ from dcim.models import Device, DeviceRole, Platform, Region, Site, SiteGroup from extras.forms import LocalConfigContextFilterForm from extras.models import ConfigTemplate -from ipam.models import L2VPN, VRF +from ipam.models import VRF from netbox.forms import NetBoxModelFilterSetForm from tenancy.forms import ContactModelFilterForm, TenancyFilterForm from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES from utilities.forms.fields import DynamicModelMultipleChoiceField, TagFilterField from virtualization.choices import * from virtualization.models import * +from vpn.models import L2VPN __all__ = ( 'ClusterFilterForm', diff --git a/netbox/virtualization/models/virtualmachines.py b/netbox/virtualization/models/virtualmachines.py index 2126f2541..1824aae99 100644 --- a/netbox/virtualization/models/virtualmachines.py +++ b/netbox/virtualization/models/virtualmachines.py @@ -358,7 +358,7 @@ class VMInterface(ComponentModel, BaseInterface, TrackingModelMixin): related_query_name='vminterface', ) l2vpn_terminations = GenericRelation( - to='ipam.L2VPNTermination', + to='vpn.L2VPNTermination', content_type_field='assigned_object_type', object_id_field='assigned_object_id', related_query_name='vminterface', diff --git a/netbox/vpn/migrations/0002_move_l2vpn.py b/netbox/vpn/migrations/0002_move_l2vpn.py new file mode 100644 index 000000000..3ec49f830 --- /dev/null +++ b/netbox/vpn/migrations/0002_move_l2vpn.py @@ -0,0 +1,73 @@ +from django.db import migrations, models +import django.db.models.deletion +import taggit.managers +import utilities.json + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0099_cachedvalue_ordering'), + ('contenttypes', '0002_remove_content_type_name'), + ('tenancy', '0012_contactassignment_custom_fields'), + ('ipam', '0068_move_l2vpn'), + ('vpn', '0001_initial'), + ] + + operations = [ + migrations.SeparateDatabaseAndState( + state_operations=[ + migrations.CreateModel( + name='L2VPN', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=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')), + ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ('tenant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='l2vpns', to='tenancy.tenant')), + ], + options={ + 'verbose_name': 'L2VPN', + 'verbose_name_plural': 'L2VPNs', + 'ordering': ('name', 'identifier'), + }, + ), + migrations.CreateModel( + name='L2VPNTermination', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)), + ('assigned_object_id', models.PositiveBigIntegerField()), + ('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={ + 'verbose_name': 'L2VPN termination', + 'verbose_name_plural': 'L2VPN terminations', + 'ordering': ('l2vpn',), + }, + ), + ], + # Tables have been renamed from ipam + database_operations=[], + ), + migrations.AddConstraint( + model_name='l2vpntermination', + constraint=models.UniqueConstraint( + fields=('assigned_object_type', 'assigned_object_id'), + name='vpn_l2vpntermination_assigned_object' + ), + ), + ] diff --git a/netbox/vpn/models/__init__.py b/netbox/vpn/models/__init__.py index 3b70eb418..2e76b980b 100644 --- a/netbox/vpn/models/__init__.py +++ b/netbox/vpn/models/__init__.py @@ -1,2 +1,3 @@ from .crypto import * +from .l2vpn import * from .tunnels import * diff --git a/netbox/ipam/models/l2vpn.py b/netbox/vpn/models/l2vpn.py similarity index 95% rename from netbox/ipam/models/l2vpn.py rename to netbox/vpn/models/l2vpn.py index a2742a8f3..5885c39d1 100644 --- a/netbox/ipam/models/l2vpn.py +++ b/netbox/vpn/models/l2vpn.py @@ -69,7 +69,7 @@ class L2VPN(ContactsMixin, PrimaryModel): return f'{self.name}' def get_absolute_url(self): - return reverse('ipam:l2vpn', args=[self.pk]) + return reverse('vpn:l2vpn', args=[self.pk]) @cached_property def can_add_termination(self): @@ -81,7 +81,7 @@ class L2VPN(ContactsMixin, PrimaryModel): class L2VPNTermination(NetBoxModel): l2vpn = models.ForeignKey( - to='ipam.L2VPN', + to='vpn.L2VPN', on_delete=models.CASCADE, related_name='terminations' ) @@ -99,7 +99,7 @@ class L2VPNTermination(NetBoxModel): clone_fields = ('l2vpn',) prerequisite_models = ( - 'ipam.L2VPN', + 'vpn.L2VPN', ) class Meta: @@ -107,7 +107,7 @@ class L2VPNTermination(NetBoxModel): constraints = ( models.UniqueConstraint( fields=('assigned_object_type', 'assigned_object_id'), - name='ipam_l2vpntermination_assigned_object' + name='vpn_l2vpntermination_assigned_object' ), ) verbose_name = _('L2VPN termination') @@ -119,7 +119,7 @@ class L2VPNTermination(NetBoxModel): return super().__str__() def get_absolute_url(self): - return reverse('ipam:l2vpntermination', args=[self.pk]) + return reverse('vpn:l2vpntermination', args=[self.pk]) def clean(self): # Only check is assigned_object is set. Required otherwise we have an Integrity Error thrown.