Move L2VPN and L2VPNTermination models from ipam to vpn

This commit is contained in:
Jeremy Stretch 2023-11-22 15:10:23 -05:00
parent 6678880db5
commit 8e9e1e9e64
28 changed files with 163 additions and 48 deletions

View File

@ -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 *

View File

@ -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__ = (

View File

@ -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',

View File

@ -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__ = [

View File

@ -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

View File

@ -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

View File

@ -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 *

View File

@ -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',

View File

@ -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',

View File

@ -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',

View File

@ -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',

View File

@ -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)

View File

@ -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

View File

@ -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',
),
],
),
]

View File

@ -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',
)

View File

@ -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'

View File

@ -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),

View File

@ -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',

View File

@ -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):

View File

@ -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):

View File

@ -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):

View File

@ -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):

View File

@ -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 *

View File

@ -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',

View File

@ -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',

View File

@ -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'
),
),
]

View File

@ -1,2 +1,3 @@
from .crypto import *
from .l2vpn import *
from .tunnels import *

View File

@ -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.