Merge branch 'netbox-community:main' into 17542-Contact_Assignment_to_vpn_tunnels

This commit is contained in:
Antoine Keranflec'h
2025-01-25 14:19:25 +01:00
committed by GitHub
550 changed files with 136453 additions and 106452 deletions

View File

@@ -1,109 +0,0 @@
import warnings
from drf_spectacular.utils import extend_schema_serializer
from netbox.api.fields import RelatedObjectCountField
from netbox.api.serializers import WritableNestedSerializer
from vpn import models
__all__ = (
'NestedIKEPolicySerializer',
'NestedIKEProposalSerializer',
'NestedIPSecPolicySerializer',
'NestedIPSecProfileSerializer',
'NestedIPSecProposalSerializer',
'NestedL2VPNSerializer',
'NestedL2VPNTerminationSerializer',
'NestedTunnelGroupSerializer',
'NestedTunnelSerializer',
'NestedTunnelTerminationSerializer',
)
# TODO: Remove in v4.2
warnings.warn(
"Dedicated nested serializers will be removed in NetBox v4.2. Use Serializer(nested=True) instead.",
DeprecationWarning
)
@extend_schema_serializer(
exclude_fields=('tunnel_count',),
)
class NestedTunnelGroupSerializer(WritableNestedSerializer):
tunnel_count = RelatedObjectCountField('tunnels')
class Meta:
model = models.TunnelGroup
fields = ['id', 'url', 'display_url', 'display', 'name', 'slug', 'tunnel_count']
class NestedTunnelSerializer(WritableNestedSerializer):
class Meta:
model = models.Tunnel
fields = ('id', 'url', 'display_url', 'display', 'name')
class NestedTunnelTerminationSerializer(WritableNestedSerializer):
class Meta:
model = models.TunnelTermination
fields = ('id', 'url', 'display_url', 'display')
class NestedIKEProposalSerializer(WritableNestedSerializer):
class Meta:
model = models.IKEProposal
fields = ('id', 'url', 'display_url', 'display', 'name')
class NestedIKEPolicySerializer(WritableNestedSerializer):
class Meta:
model = models.IKEPolicy
fields = ('id', 'url', 'display_url', 'display', 'name')
class NestedIPSecProposalSerializer(WritableNestedSerializer):
class Meta:
model = models.IPSecProposal
fields = ('id', 'url', 'display_url', 'display', 'name')
class NestedIPSecPolicySerializer(WritableNestedSerializer):
class Meta:
model = models.IPSecPolicy
fields = ('id', 'url', 'display_url', 'display', 'name')
class NestedIPSecProfileSerializer(WritableNestedSerializer):
class Meta:
model = models.IPSecProfile
fields = ('id', 'url', 'display_url', 'display', 'name')
#
# L2VPN
#
class NestedL2VPNSerializer(WritableNestedSerializer):
class Meta:
model = models.L2VPN
fields = [
'id', 'url', 'display', 'display_url', 'identifier', 'name', 'slug', 'type'
]
class NestedL2VPNTerminationSerializer(WritableNestedSerializer):
l2vpn = NestedL2VPNSerializer()
class Meta:
model = models.L2VPNTermination
fields = [
'id', 'url', 'display_url', 'display', 'l2vpn'
]

View File

@@ -64,17 +64,20 @@ class IKEPolicySerializer(NetBoxModelSerializer):
class IPSecProposalSerializer(NetBoxModelSerializer):
encryption_algorithm = ChoiceField(
choices=EncryptionAlgorithmChoices
choices=EncryptionAlgorithmChoices,
required=False
)
authentication_algorithm = ChoiceField(
choices=AuthenticationAlgorithmChoices
choices=AuthenticationAlgorithmChoices,
required=False
)
class Meta:
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')

View File

@@ -23,15 +23,23 @@ class TunnelStatusChoices(ChoiceSet):
class TunnelEncapsulationChoices(ChoiceSet):
ENCAP_GRE = 'gre'
ENCAP_IP_IP = 'ip-ip'
ENCAP_IPSEC_TRANSPORT = 'ipsec-transport'
ENCAP_IPSEC_TUNNEL = 'ipsec-tunnel'
ENCAP_IP_IP = 'ip-ip'
ENCAP_L2TP = 'l2tp'
ENCAP_OPENVPN = 'openvpn'
ENCAP_PPTP = 'pptp'
ENCAP_WIREGUARD = 'wireguard'
CHOICES = [
(ENCAP_IPSEC_TRANSPORT, _('IPsec - Transport')),
(ENCAP_IPSEC_TUNNEL, _('IPsec - Tunnel')),
(ENCAP_IP_IP, _('IP-in-IP')),
(ENCAP_GRE, _('GRE')),
(ENCAP_WIREGUARD, _('WireGuard')),
(ENCAP_OPENVPN, _('OpenVPN')),
(ENCAP_L2TP, _('L2TP')),
(ENCAP_PPTP, _('PPTP')),
]

View File

@@ -47,7 +47,8 @@ class TunnelForm(TenancyForm, NetBoxModelForm):
group = DynamicModelChoiceField(
queryset=TunnelGroup.objects.all(),
label=_('Tunnel Group'),
required=False
required=False,
quick_add=True
)
ipsec_profile = DynamicModelChoiceField(
queryset=IPSecProfile.objects.all(),
@@ -258,7 +259,7 @@ class TunnelTerminationForm(NetBoxModelForm):
class Meta:
model = TunnelTermination
fields = [
'tunnel', 'role', 'termination', 'outside_ip', 'tags',
'tunnel', 'role', 'outside_ip', 'tags',
]
def __init__(self, *args, initial=None, **kwargs):
@@ -313,7 +314,8 @@ class IKEProposalForm(NetBoxModelForm):
class IKEPolicyForm(NetBoxModelForm):
proposals = DynamicModelMultipleChoiceField(
queryset=IKEProposal.objects.all(),
label=_('Proposals')
label=_('Proposals'),
quick_add=True
)
fieldsets = (
@@ -349,7 +351,8 @@ class IPSecProposalForm(NetBoxModelForm):
class IPSecPolicyForm(NetBoxModelForm):
proposals = DynamicModelMultipleChoiceField(
queryset=IPSecProposal.objects.all(),
label=_('Proposals')
label=_('Proposals'),
quick_add=True
)
fieldsets = (

View File

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

View File

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

View File

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

View File

@@ -4,7 +4,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('vpn', '0003_ipaddress_multiple_tunnel_terminations'),
]

View File

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

View File

@@ -0,0 +1,45 @@
from django.db import migrations, models
def set_null_values(apps, schema_editor):
"""
Replace empty strings with null values.
"""
IKEPolicy = apps.get_model('vpn', 'IKEPolicy')
IKEProposal = apps.get_model('vpn', 'IKEProposal')
IPSecProposal = apps.get_model('vpn', 'IPSecProposal')
IKEPolicy.objects.filter(mode='').update(mode=None)
IKEProposal.objects.filter(authentication_algorithm='').update(authentication_algorithm=None)
IPSecProposal.objects.filter(authentication_algorithm='').update(authentication_algorithm=None)
IPSecProposal.objects.filter(encryption_algorithm='').update(encryption_algorithm=None)
class Migration(migrations.Migration):
dependencies = [
('vpn', '0005_rename_indexes'),
]
operations = [
migrations.AlterField(
model_name='ikepolicy',
name='mode',
field=models.CharField(blank=True, null=True),
),
migrations.AlterField(
model_name='ikeproposal',
name='authentication_algorithm',
field=models.CharField(blank=True, null=True),
),
migrations.AlterField(
model_name='ipsecproposal',
name='authentication_algorithm',
field=models.CharField(blank=True, null=True),
),
migrations.AlterField(
model_name='ipsecproposal',
name='encryption_algorithm',
field=models.CharField(blank=True, null=True),
),
migrations.RunPython(code=set_null_values, reverse_code=migrations.RunPython.noop),
]

View File

@@ -0,0 +1,46 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('vpn', '0006_charfield_null_choices'),
('dcim', '0197_natural_sort_collation'),
]
operations = [
migrations.AlterField(
model_name='ikepolicy',
name='name',
field=models.CharField(db_collation='natural_sort', max_length=100, unique=True),
),
migrations.AlterField(
model_name='ikeproposal',
name='name',
field=models.CharField(db_collation='natural_sort', max_length=100, unique=True),
),
migrations.AlterField(
model_name='ipsecpolicy',
name='name',
field=models.CharField(db_collation='natural_sort', max_length=100, unique=True),
),
migrations.AlterField(
model_name='ipsecprofile',
name='name',
field=models.CharField(db_collation='natural_sort', max_length=100, unique=True),
),
migrations.AlterField(
model_name='ipsecproposal',
name='name',
field=models.CharField(db_collation='natural_sort', max_length=100, unique=True),
),
migrations.AlterField(
model_name='l2vpn',
name='name',
field=models.CharField(db_collation='natural_sort', max_length=100, unique=True),
),
migrations.AlterField(
model_name='tunnel',
name='name',
field=models.CharField(db_collation='natural_sort', max_length=100, unique=True),
),
]

View File

@@ -1,6 +1,5 @@
from django.core.exceptions import ValidationError
from django.db import models
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from netbox.models import PrimaryModel
@@ -23,7 +22,8 @@ class IKEProposal(PrimaryModel):
name = models.CharField(
verbose_name=_('name'),
max_length=100,
unique=True
unique=True,
db_collation="natural_sort"
)
authentication_method = models.CharField(
verbose_name=('authentication method'),
@@ -36,7 +36,8 @@ class IKEProposal(PrimaryModel):
authentication_algorithm = models.CharField(
verbose_name=_('authentication algorithm'),
choices=AuthenticationAlgorithmChoices,
blank=True
blank=True,
null=True
)
group = models.PositiveSmallIntegerField(
verbose_name=_('group'),
@@ -62,15 +63,13 @@ class IKEProposal(PrimaryModel):
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('vpn:ikeproposal', args=[self.pk])
class IKEPolicy(PrimaryModel):
name = models.CharField(
verbose_name=_('name'),
max_length=100,
unique=True
unique=True,
db_collation="natural_sort"
)
version = models.PositiveSmallIntegerField(
verbose_name=_('version'),
@@ -80,7 +79,8 @@ class IKEPolicy(PrimaryModel):
mode = models.CharField(
verbose_name=_('mode'),
choices=IKEModeChoices,
blank=True
blank=True,
null=True
)
proposals = models.ManyToManyField(
to='vpn.IKEProposal',
@@ -107,9 +107,6 @@ class IKEPolicy(PrimaryModel):
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('vpn:ikepolicy', args=[self.pk])
def clean(self):
super().clean()
@@ -130,17 +127,20 @@ class IPSecProposal(PrimaryModel):
name = models.CharField(
verbose_name=_('name'),
max_length=100,
unique=True
unique=True,
db_collation="natural_sort"
)
encryption_algorithm = models.CharField(
verbose_name=_('encryption'),
choices=EncryptionAlgorithmChoices,
blank=True
blank=True,
null=True
)
authentication_algorithm = models.CharField(
verbose_name=_('authentication'),
choices=AuthenticationAlgorithmChoices,
blank=True
blank=True,
null=True
)
sa_lifetime_seconds = models.PositiveIntegerField(
verbose_name=_('SA lifetime (seconds)'),
@@ -167,9 +167,6 @@ class IPSecProposal(PrimaryModel):
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('vpn:ipsecproposal', args=[self.pk])
def clean(self):
super().clean()
@@ -182,7 +179,8 @@ class IPSecPolicy(PrimaryModel):
name = models.CharField(
verbose_name=_('name'),
max_length=100,
unique=True
unique=True,
db_collation="natural_sort"
)
proposals = models.ManyToManyField(
to='vpn.IPSecProposal',
@@ -212,15 +210,13 @@ class IPSecPolicy(PrimaryModel):
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('vpn:ipsecpolicy', args=[self.pk])
class IPSecProfile(PrimaryModel):
name = models.CharField(
verbose_name=_('name'),
max_length=100,
unique=True
unique=True,
db_collation="natural_sort"
)
mode = models.CharField(
verbose_name=_('mode'),
@@ -252,6 +248,3 @@ class IPSecProfile(PrimaryModel):
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('vpn:ipsecprofile', args=[self.pk])

View File

@@ -1,7 +1,6 @@
from django.contrib.contenttypes.fields import GenericForeignKey
from django.core.exceptions import ValidationError
from django.db import models
from django.urls import reverse
from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _
@@ -21,7 +20,8 @@ class L2VPN(ContactsMixin, PrimaryModel):
name = models.CharField(
verbose_name=_('name'),
max_length=100,
unique=True
unique=True,
db_collation="natural_sort"
)
slug = models.SlugField(
verbose_name=_('slug'),
@@ -68,9 +68,6 @@ class L2VPN(ContactsMixin, PrimaryModel):
return f'{self.name} ({self.identifier})'
return f'{self.name}'
def get_absolute_url(self):
return reverse('vpn:l2vpn', args=[self.pk])
@cached_property
def can_add_termination(self):
if self.type in L2VPNTypeChoices.P2P and self.terminations.count() >= 2:
@@ -121,9 +118,6 @@ class L2VPNTermination(NetBoxModel):
return f'{self.assigned_object} <> {self.l2vpn}'
return super().__str__()
def get_absolute_url(self):
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.
if self.assigned_object:

View File

@@ -26,15 +26,13 @@ class TunnelGroup(ContactsMixin, OrganizationalModel):
verbose_name = _('tunnel group')
verbose_name_plural = _('tunnel groups')
def get_absolute_url(self):
return reverse('vpn:tunnelgroup', args=[self.pk])
class Tunnel(ContactsMixin, PrimaryModel):
name = models.CharField(
verbose_name=_('name'),
max_length=100,
unique=True
unique=True,
db_collation="natural_sort"
)
status = models.CharField(
verbose_name=_('status'),
@@ -97,9 +95,6 @@ class Tunnel(ContactsMixin, PrimaryModel):
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('vpn:tunnel', args=[self.pk])
def get_status_color(self):
return TunnelStatusChoices.colors.get(self.status)

View File

@@ -1,89 +1,39 @@
from django.urls import include, path
from utilities.urls import get_model_urls
from . import views
from . import views # noqa F401
app_name = 'vpn'
urlpatterns = [
# Tunnel groups
path('tunnel-groups/', views.TunnelGroupListView.as_view(), name='tunnelgroup_list'),
path('tunnel-groups/add/', views.TunnelGroupEditView.as_view(), name='tunnelgroup_add'),
path('tunnel-groups/import/', views.TunnelGroupBulkImportView.as_view(), name='tunnelgroup_import'),
path('tunnel-groups/edit/', views.TunnelGroupBulkEditView.as_view(), name='tunnelgroup_bulk_edit'),
path('tunnel-groups/delete/', views.TunnelGroupBulkDeleteView.as_view(), name='tunnelgroup_bulk_delete'),
path('tunnel-groups/', include(get_model_urls('vpn', 'tunnelgroup', detail=False))),
path('tunnel-groups/<int:pk>/', include(get_model_urls('vpn', 'tunnelgroup'))),
# Tunnels
path('tunnels/', views.TunnelListView.as_view(), name='tunnel_list'),
path('tunnels/add/', views.TunnelEditView.as_view(), name='tunnel_add'),
path('tunnels/import/', views.TunnelBulkImportView.as_view(), name='tunnel_import'),
path('tunnels/edit/', views.TunnelBulkEditView.as_view(), name='tunnel_bulk_edit'),
path('tunnels/delete/', views.TunnelBulkDeleteView.as_view(), name='tunnel_bulk_delete'),
path('tunnels/', include(get_model_urls('vpn', 'tunnel', detail=False))),
path('tunnels/<int:pk>/', include(get_model_urls('vpn', 'tunnel'))),
# Tunnel terminations
path('tunnel-terminations/', views.TunnelTerminationListView.as_view(), name='tunneltermination_list'),
path('tunnel-terminations/add/', views.TunnelTerminationEditView.as_view(), name='tunneltermination_add'),
path('tunnel-terminations/import/', views.TunnelTerminationBulkImportView.as_view(), name='tunneltermination_import'),
path('tunnel-terminations/edit/', views.TunnelTerminationBulkEditView.as_view(), name='tunneltermination_bulk_edit'),
path('tunnel-terminations/delete/', views.TunnelTerminationBulkDeleteView.as_view(), name='tunneltermination_bulk_delete'),
path('tunnel-terminations/', include(get_model_urls('vpn', 'tunneltermination', detail=False))),
path('tunnel-terminations/<int:pk>/', include(get_model_urls('vpn', 'tunneltermination'))),
# IKE proposals
path('ike-proposals/', views.IKEProposalListView.as_view(), name='ikeproposal_list'),
path('ike-proposals/add/', views.IKEProposalEditView.as_view(), name='ikeproposal_add'),
path('ike-proposals/import/', views.IKEProposalBulkImportView.as_view(), name='ikeproposal_import'),
path('ike-proposals/edit/', views.IKEProposalBulkEditView.as_view(), name='ikeproposal_bulk_edit'),
path('ike-proposals/delete/', views.IKEProposalBulkDeleteView.as_view(), name='ikeproposal_bulk_delete'),
path('ike-proposals/', include(get_model_urls('vpn', 'ikeproposal', detail=False))),
path('ike-proposals/<int:pk>/', include(get_model_urls('vpn', 'ikeproposal'))),
# IKE policies
path('ike-policies/', views.IKEPolicyListView.as_view(), name='ikepolicy_list'),
path('ike-policies/add/', views.IKEPolicyEditView.as_view(), name='ikepolicy_add'),
path('ike-policies/import/', views.IKEPolicyBulkImportView.as_view(), name='ikepolicy_import'),
path('ike-policies/edit/', views.IKEPolicyBulkEditView.as_view(), name='ikepolicy_bulk_edit'),
path('ike-policies/delete/', views.IKEPolicyBulkDeleteView.as_view(), name='ikepolicy_bulk_delete'),
path('ike-policies/', include(get_model_urls('vpn', 'ikepolicy', detail=False))),
path('ike-policies/<int:pk>/', include(get_model_urls('vpn', 'ikepolicy'))),
# IPSec proposals
path('ipsec-proposals/', views.IPSecProposalListView.as_view(), name='ipsecproposal_list'),
path('ipsec-proposals/add/', views.IPSecProposalEditView.as_view(), name='ipsecproposal_add'),
path('ipsec-proposals/import/', views.IPSecProposalBulkImportView.as_view(), name='ipsecproposal_import'),
path('ipsec-proposals/edit/', views.IPSecProposalBulkEditView.as_view(), name='ipsecproposal_bulk_edit'),
path('ipsec-proposals/delete/', views.IPSecProposalBulkDeleteView.as_view(), name='ipsecproposal_bulk_delete'),
path('ipsec-proposals/', include(get_model_urls('vpn', 'ipsecproposal', detail=False))),
path('ipsec-proposals/<int:pk>/', include(get_model_urls('vpn', 'ipsecproposal'))),
# IPSec policies
path('ipsec-policies/', views.IPSecPolicyListView.as_view(), name='ipsecpolicy_list'),
path('ipsec-policies/add/', views.IPSecPolicyEditView.as_view(), name='ipsecpolicy_add'),
path('ipsec-policies/import/', views.IPSecPolicyBulkImportView.as_view(), name='ipsecpolicy_import'),
path('ipsec-policies/edit/', views.IPSecPolicyBulkEditView.as_view(), name='ipsecpolicy_bulk_edit'),
path('ipsec-policies/delete/', views.IPSecPolicyBulkDeleteView.as_view(), name='ipsecpolicy_bulk_delete'),
path('ipsec-policies/', include(get_model_urls('vpn', 'ipsecpolicy', detail=False))),
path('ipsec-policies/<int:pk>/', include(get_model_urls('vpn', 'ipsecpolicy'))),
# IPSec profiles
path('ipsec-profiles/', views.IPSecProfileListView.as_view(), name='ipsecprofile_list'),
path('ipsec-profiles/add/', views.IPSecProfileEditView.as_view(), name='ipsecprofile_add'),
path('ipsec-profiles/import/', views.IPSecProfileBulkImportView.as_view(), name='ipsecprofile_import'),
path('ipsec-profiles/edit/', views.IPSecProfileBulkEditView.as_view(), name='ipsecprofile_bulk_edit'),
path('ipsec-profiles/delete/', views.IPSecProfileBulkDeleteView.as_view(), name='ipsecprofile_bulk_delete'),
path('ipsec-profiles/', include(get_model_urls('vpn', 'ipsecprofile', detail=False))),
path('ipsec-profiles/<int:pk>/', include(get_model_urls('vpn', 'ipsecprofile'))),
# L2VPN
path('l2vpns/', views.L2VPNListView.as_view(), name='l2vpn_list'),
path('l2vpns/add/', views.L2VPNEditView.as_view(), name='l2vpn_add'),
path('l2vpns/import/', views.L2VPNBulkImportView.as_view(), name='l2vpn_import'),
path('l2vpns/edit/', views.L2VPNBulkEditView.as_view(), name='l2vpn_bulk_edit'),
path('l2vpns/delete/', views.L2VPNBulkDeleteView.as_view(), name='l2vpn_bulk_delete'),
path('l2vpns/', include(get_model_urls('vpn', 'l2vpn', detail=False))),
path('l2vpns/<int:pk>/', include(get_model_urls('vpn', 'l2vpn'))),
# L2VPN terminations
path('l2vpn-terminations/', views.L2VPNTerminationListView.as_view(), name='l2vpntermination_list'),
path('l2vpn-terminations/add/', views.L2VPNTerminationEditView.as_view(), name='l2vpntermination_add'),
path('l2vpn-terminations/import/', views.L2VPNTerminationBulkImportView.as_view(), name='l2vpntermination_import'),
path('l2vpn-terminations/edit/', views.L2VPNTerminationBulkEditView.as_view(), name='l2vpntermination_bulk_edit'),
path('l2vpn-terminations/delete/', views.L2VPNTerminationBulkDeleteView.as_view(), name='l2vpntermination_bulk_delete'),
path('l2vpn-terminations/', include(get_model_urls('vpn', 'l2vpntermination', detail=False))),
path('l2vpn-terminations/<int:pk>/', include(get_model_urls('vpn', 'l2vpntermination'))),
]

View File

@@ -11,6 +11,7 @@ from .models import *
# Tunnel groups
#
@register_model_view(TunnelGroup, 'list', path='', detail=False)
class TunnelGroupListView(generic.ObjectListView):
queryset = TunnelGroup.objects.annotate(
tunnel_count=count_related(Tunnel, 'group')
@@ -30,6 +31,7 @@ class TunnelGroupView(GetRelatedModelsMixin, generic.ObjectView):
}
@register_model_view(TunnelGroup, 'add', detail=False)
@register_model_view(TunnelGroup, 'edit')
class TunnelGroupEditView(generic.ObjectEditView):
queryset = TunnelGroup.objects.all()
@@ -41,11 +43,13 @@ class TunnelGroupDeleteView(generic.ObjectDeleteView):
queryset = TunnelGroup.objects.all()
@register_model_view(TunnelGroup, 'bulk_import', detail=False)
class TunnelGroupBulkImportView(generic.BulkImportView):
queryset = TunnelGroup.objects.all()
model_form = forms.TunnelGroupImportForm
@register_model_view(TunnelGroup, 'bulk_edit', path='edit', detail=False)
class TunnelGroupBulkEditView(generic.BulkEditView):
queryset = TunnelGroup.objects.annotate(
tunnel_count=count_related(Tunnel, 'group')
@@ -55,6 +59,7 @@ class TunnelGroupBulkEditView(generic.BulkEditView):
form = forms.TunnelGroupBulkEditForm
@register_model_view(TunnelGroup, 'bulk_delete', path='delete', detail=False)
class TunnelGroupBulkDeleteView(generic.BulkDeleteView):
queryset = TunnelGroup.objects.annotate(
tunnel_count=count_related(Tunnel, 'group')
@@ -70,6 +75,7 @@ class TunnelGroupContactsView(ObjectContactsView):
# Tunnels
#
@register_model_view(Tunnel, 'list', path='', detail=False)
class TunnelListView(generic.ObjectListView):
queryset = Tunnel.objects.annotate(
count_terminations=count_related(TunnelTermination, 'tunnel')
@@ -84,6 +90,7 @@ class TunnelView(generic.ObjectView):
queryset = Tunnel.objects.all()
@register_model_view(Tunnel, 'add', detail=False)
@register_model_view(Tunnel, 'edit')
class TunnelEditView(generic.ObjectEditView):
queryset = Tunnel.objects.all()
@@ -103,11 +110,13 @@ class TunnelDeleteView(generic.ObjectDeleteView):
queryset = Tunnel.objects.all()
@register_model_view(Tunnel, 'bulk_import', detail=False)
class TunnelBulkImportView(generic.BulkImportView):
queryset = Tunnel.objects.all()
model_form = forms.TunnelImportForm
@register_model_view(Tunnel, 'bulk_edit', path='edit', detail=False)
class TunnelBulkEditView(generic.BulkEditView):
queryset = Tunnel.objects.annotate(
count_terminations=count_related(TunnelTermination, 'tunnel')
@@ -117,6 +126,7 @@ class TunnelBulkEditView(generic.BulkEditView):
form = forms.TunnelBulkEditForm
@register_model_view(Tunnel, 'bulk_delete', path='delete', detail=False)
class TunnelBulkDeleteView(generic.BulkDeleteView):
queryset = Tunnel.objects.annotate(
count_terminations=count_related(TunnelTermination, 'tunnel')
@@ -132,6 +142,7 @@ class TunnelContactsView(ObjectContactsView):
# Tunnel terminations
#
@register_model_view(TunnelTermination, 'list', path='', detail=False)
class TunnelTerminationListView(generic.ObjectListView):
queryset = TunnelTermination.objects.all()
filterset = filtersets.TunnelTerminationFilterSet
@@ -144,6 +155,7 @@ class TunnelTerminationView(generic.ObjectView):
queryset = TunnelTermination.objects.all()
@register_model_view(TunnelTermination, 'add', detail=False)
@register_model_view(TunnelTermination, 'edit')
class TunnelTerminationEditView(generic.ObjectEditView):
queryset = TunnelTermination.objects.all()
@@ -155,11 +167,13 @@ class TunnelTerminationDeleteView(generic.ObjectDeleteView):
queryset = TunnelTermination.objects.all()
@register_model_view(TunnelTermination, 'bulk_import', detail=False)
class TunnelTerminationBulkImportView(generic.BulkImportView):
queryset = TunnelTermination.objects.all()
model_form = forms.TunnelTerminationImportForm
@register_model_view(TunnelTermination, 'bulk_edit', path='edit', detail=False)
class TunnelTerminationBulkEditView(generic.BulkEditView):
queryset = TunnelTermination.objects.all()
filterset = filtersets.TunnelTerminationFilterSet
@@ -167,6 +181,7 @@ class TunnelTerminationBulkEditView(generic.BulkEditView):
form = forms.TunnelTerminationBulkEditForm
@register_model_view(TunnelTermination, 'bulk_delete', path='delete', detail=False)
class TunnelTerminationBulkDeleteView(generic.BulkDeleteView):
queryset = TunnelTermination.objects.all()
filterset = filtersets.TunnelTerminationFilterSet
@@ -177,6 +192,7 @@ class TunnelTerminationBulkDeleteView(generic.BulkDeleteView):
# IKE proposals
#
@register_model_view(IKEProposal, 'list', path='', detail=False)
class IKEProposalListView(generic.ObjectListView):
queryset = IKEProposal.objects.all()
filterset = filtersets.IKEProposalFilterSet
@@ -189,6 +205,7 @@ class IKEProposalView(generic.ObjectView):
queryset = IKEProposal.objects.all()
@register_model_view(IKEProposal, 'add', detail=False)
@register_model_view(IKEProposal, 'edit')
class IKEProposalEditView(generic.ObjectEditView):
queryset = IKEProposal.objects.all()
@@ -200,11 +217,13 @@ class IKEProposalDeleteView(generic.ObjectDeleteView):
queryset = IKEProposal.objects.all()
@register_model_view(IKEProposal, 'bulk_import', detail=False)
class IKEProposalBulkImportView(generic.BulkImportView):
queryset = IKEProposal.objects.all()
model_form = forms.IKEProposalImportForm
@register_model_view(IKEProposal, 'bulk_edit', path='edit', detail=False)
class IKEProposalBulkEditView(generic.BulkEditView):
queryset = IKEProposal.objects.all()
filterset = filtersets.IKEProposalFilterSet
@@ -212,6 +231,7 @@ class IKEProposalBulkEditView(generic.BulkEditView):
form = forms.IKEProposalBulkEditForm
@register_model_view(IKEProposal, 'bulk_delete', path='delete', detail=False)
class IKEProposalBulkDeleteView(generic.BulkDeleteView):
queryset = IKEProposal.objects.all()
filterset = filtersets.IKEProposalFilterSet
@@ -222,6 +242,7 @@ class IKEProposalBulkDeleteView(generic.BulkDeleteView):
# IKE policies
#
@register_model_view(IKEPolicy, 'list', path='', detail=False)
class IKEPolicyListView(generic.ObjectListView):
queryset = IKEPolicy.objects.all()
filterset = filtersets.IKEPolicyFilterSet
@@ -234,6 +255,7 @@ class IKEPolicyView(generic.ObjectView):
queryset = IKEPolicy.objects.all()
@register_model_view(IKEPolicy, 'add', detail=False)
@register_model_view(IKEPolicy, 'edit')
class IKEPolicyEditView(generic.ObjectEditView):
queryset = IKEPolicy.objects.all()
@@ -245,11 +267,13 @@ class IKEPolicyDeleteView(generic.ObjectDeleteView):
queryset = IKEPolicy.objects.all()
@register_model_view(IKEPolicy, 'bulk_import', detail=False)
class IKEPolicyBulkImportView(generic.BulkImportView):
queryset = IKEPolicy.objects.all()
model_form = forms.IKEPolicyImportForm
@register_model_view(IKEPolicy, 'bulk_edit', path='edit', detail=False)
class IKEPolicyBulkEditView(generic.BulkEditView):
queryset = IKEPolicy.objects.all()
filterset = filtersets.IKEPolicyFilterSet
@@ -257,6 +281,7 @@ class IKEPolicyBulkEditView(generic.BulkEditView):
form = forms.IKEPolicyBulkEditForm
@register_model_view(IKEPolicy, 'bulk_delete', path='delete', detail=False)
class IKEPolicyBulkDeleteView(generic.BulkDeleteView):
queryset = IKEPolicy.objects.all()
filterset = filtersets.IKEPolicyFilterSet
@@ -267,6 +292,7 @@ class IKEPolicyBulkDeleteView(generic.BulkDeleteView):
# IPSec proposals
#
@register_model_view(IPSecProposal, 'list', path='', detail=False)
class IPSecProposalListView(generic.ObjectListView):
queryset = IPSecProposal.objects.all()
filterset = filtersets.IPSecProposalFilterSet
@@ -279,6 +305,7 @@ class IPSecProposalView(generic.ObjectView):
queryset = IPSecProposal.objects.all()
@register_model_view(IPSecProposal, 'add', detail=False)
@register_model_view(IPSecProposal, 'edit')
class IPSecProposalEditView(generic.ObjectEditView):
queryset = IPSecProposal.objects.all()
@@ -290,11 +317,13 @@ class IPSecProposalDeleteView(generic.ObjectDeleteView):
queryset = IPSecProposal.objects.all()
@register_model_view(IPSecProposal, 'bulk_import', detail=False)
class IPSecProposalBulkImportView(generic.BulkImportView):
queryset = IPSecProposal.objects.all()
model_form = forms.IPSecProposalImportForm
@register_model_view(IPSecProposal, 'bulk_edit', path='edit', detail=False)
class IPSecProposalBulkEditView(generic.BulkEditView):
queryset = IPSecProposal.objects.all()
filterset = filtersets.IPSecProposalFilterSet
@@ -302,6 +331,7 @@ class IPSecProposalBulkEditView(generic.BulkEditView):
form = forms.IPSecProposalBulkEditForm
@register_model_view(IPSecProposal, 'bulk_delete', path='delete', detail=False)
class IPSecProposalBulkDeleteView(generic.BulkDeleteView):
queryset = IPSecProposal.objects.all()
filterset = filtersets.IPSecProposalFilterSet
@@ -312,6 +342,7 @@ class IPSecProposalBulkDeleteView(generic.BulkDeleteView):
# IPSec policies
#
@register_model_view(IPSecPolicy, 'list', path='', detail=False)
class IPSecPolicyListView(generic.ObjectListView):
queryset = IPSecPolicy.objects.all()
filterset = filtersets.IPSecPolicyFilterSet
@@ -324,6 +355,7 @@ class IPSecPolicyView(generic.ObjectView):
queryset = IPSecPolicy.objects.all()
@register_model_view(IPSecPolicy, 'add', detail=False)
@register_model_view(IPSecPolicy, 'edit')
class IPSecPolicyEditView(generic.ObjectEditView):
queryset = IPSecPolicy.objects.all()
@@ -335,11 +367,13 @@ class IPSecPolicyDeleteView(generic.ObjectDeleteView):
queryset = IPSecPolicy.objects.all()
@register_model_view(IPSecPolicy, 'bulk_import', detail=False)
class IPSecPolicyBulkImportView(generic.BulkImportView):
queryset = IPSecPolicy.objects.all()
model_form = forms.IPSecPolicyImportForm
@register_model_view(IPSecPolicy, 'bulk_edit', path='edit', detail=False)
class IPSecPolicyBulkEditView(generic.BulkEditView):
queryset = IPSecPolicy.objects.all()
filterset = filtersets.IPSecPolicyFilterSet
@@ -347,6 +381,7 @@ class IPSecPolicyBulkEditView(generic.BulkEditView):
form = forms.IPSecPolicyBulkEditForm
@register_model_view(IPSecPolicy, 'bulk_delete', path='delete', detail=False)
class IPSecPolicyBulkDeleteView(generic.BulkDeleteView):
queryset = IPSecPolicy.objects.all()
filterset = filtersets.IPSecPolicyFilterSet
@@ -357,6 +392,7 @@ class IPSecPolicyBulkDeleteView(generic.BulkDeleteView):
# IPSec profiles
#
@register_model_view(IPSecProfile, 'list', path='', detail=False)
class IPSecProfileListView(generic.ObjectListView):
queryset = IPSecProfile.objects.all()
filterset = filtersets.IPSecProfileFilterSet
@@ -369,6 +405,7 @@ class IPSecProfileView(generic.ObjectView):
queryset = IPSecProfile.objects.all()
@register_model_view(IPSecProfile, 'add', detail=False)
@register_model_view(IPSecProfile, 'edit')
class IPSecProfileEditView(generic.ObjectEditView):
queryset = IPSecProfile.objects.all()
@@ -380,11 +417,13 @@ class IPSecProfileDeleteView(generic.ObjectDeleteView):
queryset = IPSecProfile.objects.all()
@register_model_view(IPSecProfile, 'bulk_import', detail=False)
class IPSecProfileBulkImportView(generic.BulkImportView):
queryset = IPSecProfile.objects.all()
model_form = forms.IPSecProfileImportForm
@register_model_view(IPSecProfile, 'bulk_edit', path='edit', detail=False)
class IPSecProfileBulkEditView(generic.BulkEditView):
queryset = IPSecProfile.objects.all()
filterset = filtersets.IPSecProfileFilterSet
@@ -392,14 +431,18 @@ class IPSecProfileBulkEditView(generic.BulkEditView):
form = forms.IPSecProfileBulkEditForm
@register_model_view(IPSecProfile, 'bulk_delete', path='delete', detail=False)
class IPSecProfileBulkDeleteView(generic.BulkDeleteView):
queryset = IPSecProfile.objects.all()
filterset = filtersets.IPSecProfileFilterSet
table = tables.IPSecProfileTable
#
# L2VPN
#
@register_model_view(L2VPN, 'list', path='', detail=False)
class L2VPNListView(generic.ObjectListView):
queryset = L2VPN.objects.all()
table = tables.L2VPNTable
@@ -427,6 +470,7 @@ class L2VPNView(generic.ObjectView):
}
@register_model_view(L2VPN, 'add', detail=False)
@register_model_view(L2VPN, 'edit')
class L2VPNEditView(generic.ObjectEditView):
queryset = L2VPN.objects.all()
@@ -438,11 +482,13 @@ class L2VPNDeleteView(generic.ObjectDeleteView):
queryset = L2VPN.objects.all()
@register_model_view(L2VPN, 'bulk_import', detail=False)
class L2VPNBulkImportView(generic.BulkImportView):
queryset = L2VPN.objects.all()
model_form = forms.L2VPNImportForm
@register_model_view(L2VPN, 'bulk_edit', path='edit', detail=False)
class L2VPNBulkEditView(generic.BulkEditView):
queryset = L2VPN.objects.all()
filterset = filtersets.L2VPNFilterSet
@@ -450,6 +496,7 @@ class L2VPNBulkEditView(generic.BulkEditView):
form = forms.L2VPNBulkEditForm
@register_model_view(L2VPN, 'bulk_delete', path='delete', detail=False)
class L2VPNBulkDeleteView(generic.BulkDeleteView):
queryset = L2VPN.objects.all()
filterset = filtersets.L2VPNFilterSet
@@ -465,6 +512,7 @@ class L2VPNContactsView(ObjectContactsView):
# L2VPN terminations
#
@register_model_view(L2VPNTermination, 'list', path='', detail=False)
class L2VPNTerminationListView(generic.ObjectListView):
queryset = L2VPNTermination.objects.all()
table = tables.L2VPNTerminationTable
@@ -477,6 +525,7 @@ class L2VPNTerminationView(generic.ObjectView):
queryset = L2VPNTermination.objects.all()
@register_model_view(L2VPNTermination, 'add', detail=False)
@register_model_view(L2VPNTermination, 'edit')
class L2VPNTerminationEditView(generic.ObjectEditView):
queryset = L2VPNTermination.objects.all()
@@ -488,11 +537,13 @@ class L2VPNTerminationDeleteView(generic.ObjectDeleteView):
queryset = L2VPNTermination.objects.all()
@register_model_view(L2VPNTermination, 'bulk_import', detail=False)
class L2VPNTerminationBulkImportView(generic.BulkImportView):
queryset = L2VPNTermination.objects.all()
model_form = forms.L2VPNTerminationImportForm
@register_model_view(L2VPNTermination, 'bulk_edit', path='edit', detail=False)
class L2VPNTerminationBulkEditView(generic.BulkEditView):
queryset = L2VPNTermination.objects.all()
filterset = filtersets.L2VPNTerminationFilterSet
@@ -500,6 +551,7 @@ class L2VPNTerminationBulkEditView(generic.BulkEditView):
form = forms.L2VPNTerminationBulkEditForm
@register_model_view(L2VPNTermination, 'bulk_delete', path='delete', detail=False)
class L2VPNTerminationBulkDeleteView(generic.BulkDeleteView):
queryset = L2VPNTermination.objects.all()
filterset = filtersets.L2VPNTerminationFilterSet