mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-22 23:46:44 -06:00
Rename interface to termination on CableTermination
This commit is contained in:
parent
dbed518354
commit
dda4071b3a
@ -20,17 +20,17 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
{% if object.interface.device %}
|
||||
{% if object.termination.device %}
|
||||
{% trans "Device" %}
|
||||
{% elif object.interface.virtual_machine %}
|
||||
{% elif object.termination.virtual_machine %}
|
||||
{% trans "Virtual Machine" %}
|
||||
{% endif %}
|
||||
</th>
|
||||
<td>{{ object.interface.parent_object|linkify }}</td>
|
||||
<td>{{ object.termination.parent_object|linkify }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{% trans "Interface" %}</th>
|
||||
<td>{{ object.interface|linkify }}</td>
|
||||
<td>{{ object.termination|linkify }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{% trans "Outside IP" %}</th>
|
||||
|
@ -58,10 +58,10 @@ class TunnelTerminationSerializer(NetBoxModelSerializer):
|
||||
role = ChoiceField(
|
||||
choices=TunnelTerminationRoleChoices
|
||||
)
|
||||
interface_type = ContentTypeField(
|
||||
termination_type = ContentTypeField(
|
||||
queryset=ContentType.objects.all()
|
||||
)
|
||||
interface = serializers.SerializerMethodField(
|
||||
termination = serializers.SerializerMethodField(
|
||||
read_only=True
|
||||
)
|
||||
outside_ip = NestedIPAddressSerializer(
|
||||
@ -72,15 +72,15 @@ class TunnelTerminationSerializer(NetBoxModelSerializer):
|
||||
class Meta:
|
||||
model = TunnelTermination
|
||||
fields = (
|
||||
'id', 'url', 'display', 'tunnel', 'role', 'interface_type', 'interface_id', 'interface', 'outside_ip',
|
||||
'id', 'url', 'display', 'tunnel', 'role', 'termination_type', 'termination_id', 'termination', 'outside_ip',
|
||||
'tags', 'custom_fields', 'created', 'last_updated',
|
||||
)
|
||||
|
||||
@extend_schema_field(serializers.JSONField(allow_null=True))
|
||||
def get_interface(self, obj):
|
||||
serializer = get_serializer_for_model(obj.interface, prefix=NESTED_SERIALIZER_PREFIX)
|
||||
def get_termination(self, obj):
|
||||
serializer = get_serializer_for_model(obj.termination, prefix=NESTED_SERIALIZER_PREFIX)
|
||||
context = {'request': self.context['request']}
|
||||
return serializer(obj.interface, context=context).data
|
||||
return serializer(obj.termination, context=context).data
|
||||
|
||||
|
||||
class IKEProposalSerializer(NetBoxModelSerializer):
|
||||
|
@ -78,12 +78,12 @@ class TunnelTerminationImportForm(NetBoxModelImportForm):
|
||||
to_field_name='name',
|
||||
help_text=_('Parent VM of assigned interface')
|
||||
)
|
||||
interface = CSVModelChoiceField(
|
||||
label=_('Interface'),
|
||||
termination = CSVModelChoiceField(
|
||||
label=_('Termination'),
|
||||
queryset=Interface.objects.none(), # Can also refer to VMInterface
|
||||
required=False,
|
||||
to_field_name='name',
|
||||
help_text=_('Assigned interface')
|
||||
help_text=_('Device or virtual machine interface')
|
||||
)
|
||||
outside_ip = CSVModelChoiceField(
|
||||
label=_('Outside IP'),
|
||||
@ -103,21 +103,21 @@ class TunnelTerminationImportForm(NetBoxModelImportForm):
|
||||
|
||||
if data:
|
||||
|
||||
# Limit interface queryset by assigned device/VM
|
||||
# Limit termination queryset by assigned device/VM
|
||||
if data.get('device'):
|
||||
self.fields['interface'].queryset = Interface.objects.filter(
|
||||
self.fields['termination'].queryset = Interface.objects.filter(
|
||||
**{f"device__{self.fields['device'].to_field_name}": data['device']}
|
||||
)
|
||||
elif data.get('virtual_machine'):
|
||||
self.fields['interface'].queryset = VMInterface.objects.filter(
|
||||
self.fields['termination'].queryset = VMInterface.objects.filter(
|
||||
**{f"virtual_machine__{self.fields['virtual_machine'].to_field_name}": data['virtual_machine']}
|
||||
)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
|
||||
# Set interface assignment
|
||||
if self.cleaned_data.get('interface'):
|
||||
self.instance.interface = self.cleaned_data['interface']
|
||||
# Assign termination object
|
||||
if self.cleaned_data.get('termination'):
|
||||
self.instance.termination = self.cleaned_data['termination']
|
||||
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
|
@ -65,7 +65,7 @@ class TunnelCreateForm(TunnelForm):
|
||||
selector=True,
|
||||
label=_('Device')
|
||||
)
|
||||
termination1_interface = DynamicModelChoiceField(
|
||||
termination1_termination = DynamicModelChoiceField(
|
||||
queryset=Interface.objects.all(),
|
||||
required=False,
|
||||
label=_('Interface'),
|
||||
@ -100,7 +100,7 @@ class TunnelCreateForm(TunnelForm):
|
||||
selector=True,
|
||||
label=_('Device')
|
||||
)
|
||||
termination2_interface = DynamicModelChoiceField(
|
||||
termination2_termination = DynamicModelChoiceField(
|
||||
queryset=Interface.objects.all(),
|
||||
required=False,
|
||||
label=_('Interface'),
|
||||
@ -122,11 +122,11 @@ class TunnelCreateForm(TunnelForm):
|
||||
(_('Security'), ('ipsec_profile',)),
|
||||
(_('Tenancy'), ('tenant_group', 'tenant')),
|
||||
(_('First Termination'), (
|
||||
'termination1_role', 'termination1_type', 'termination1_parent', 'termination1_interface',
|
||||
'termination1_role', 'termination1_type', 'termination1_parent', 'termination1_termination',
|
||||
'termination1_outside_ip',
|
||||
)),
|
||||
(_('Second Termination'), (
|
||||
'termination2_role', 'termination2_type', 'termination2_parent', 'termination2_interface',
|
||||
'termination2_role', 'termination2_type', 'termination2_parent', 'termination2_termination',
|
||||
'termination2_outside_ip',
|
||||
)),
|
||||
)
|
||||
@ -137,8 +137,8 @@ class TunnelCreateForm(TunnelForm):
|
||||
if initial and initial.get('termination1_type') == TunnelTerminationTypeChoices.TYPE_VIRUTALMACHINE:
|
||||
self.fields['termination1_parent'].label = _('Virtual Machine')
|
||||
self.fields['termination1_parent'].queryset = VirtualMachine.objects.all()
|
||||
self.fields['termination1_interface'].queryset = VMInterface.objects.all()
|
||||
self.fields['termination1_interface'].widget.add_query_params({
|
||||
self.fields['termination1_termination'].queryset = VMInterface.objects.all()
|
||||
self.fields['termination1_termination'].widget.add_query_params({
|
||||
'virtual_machine_id': '$termination1_parent',
|
||||
})
|
||||
self.fields['termination1_outside_ip'].widget.add_query_params({
|
||||
@ -148,8 +148,8 @@ class TunnelCreateForm(TunnelForm):
|
||||
if initial and initial.get('termination2_type') == TunnelTerminationTypeChoices.TYPE_VIRUTALMACHINE:
|
||||
self.fields['termination2_parent'].label = _('Virtual Machine')
|
||||
self.fields['termination2_parent'].queryset = VirtualMachine.objects.all()
|
||||
self.fields['termination2_interface'].queryset = VMInterface.objects.all()
|
||||
self.fields['termination2_interface'].widget.add_query_params({
|
||||
self.fields['termination2_termination'].queryset = VMInterface.objects.all()
|
||||
self.fields['termination2_termination'].widget.add_query_params({
|
||||
'virtual_machine_id': '$termination2_parent',
|
||||
})
|
||||
self.fields['termination2_outside_ip'].widget.add_query_params({
|
||||
@ -162,7 +162,7 @@ class TunnelCreateForm(TunnelForm):
|
||||
# Validate attributes for each termination (if any)
|
||||
for term in ('termination1', 'termination2'):
|
||||
required_parameters = (
|
||||
f'{term}_role', f'{term}_parent', f'{term}_interface',
|
||||
f'{term}_role', f'{term}_parent', f'{term}_termination',
|
||||
)
|
||||
parameters = (
|
||||
*required_parameters,
|
||||
@ -179,20 +179,20 @@ class TunnelCreateForm(TunnelForm):
|
||||
instance = super().save(*args, **kwargs)
|
||||
|
||||
# Create first termination
|
||||
if self.cleaned_data['termination1_interface']:
|
||||
if self.cleaned_data['termination1_termination']:
|
||||
TunnelTermination.objects.create(
|
||||
tunnel=instance,
|
||||
role=self.cleaned_data['termination1_role'],
|
||||
interface=self.cleaned_data['termination1_interface'],
|
||||
termination=self.cleaned_data['termination1_termination'],
|
||||
outside_ip=self.cleaned_data['termination1_outside_ip'],
|
||||
)
|
||||
|
||||
# Create second termination, if defined
|
||||
if self.cleaned_data['termination2_interface']:
|
||||
if self.cleaned_data['termination2_termination']:
|
||||
TunnelTermination.objects.create(
|
||||
tunnel=instance,
|
||||
role=self.cleaned_data['termination2_role'],
|
||||
interface=self.cleaned_data['termination2_interface'],
|
||||
termination=self.cleaned_data['termination2_termination'],
|
||||
outside_ip=self.cleaned_data.get('termination1_outside_ip'),
|
||||
)
|
||||
|
||||
@ -213,7 +213,7 @@ class TunnelTerminationForm(NetBoxModelForm):
|
||||
selector=True,
|
||||
label=_('Device')
|
||||
)
|
||||
interface = DynamicModelChoiceField(
|
||||
termination = DynamicModelChoiceField(
|
||||
queryset=Interface.objects.all(),
|
||||
label=_('Interface'),
|
||||
query_params={
|
||||
@ -230,13 +230,13 @@ class TunnelTerminationForm(NetBoxModelForm):
|
||||
)
|
||||
|
||||
fieldsets = (
|
||||
(None, ('tunnel', 'role', 'type', 'parent', 'interface', 'outside_ip', 'tags')),
|
||||
(None, ('tunnel', 'role', 'type', 'parent', 'termination', 'outside_ip', 'tags')),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = TunnelTermination
|
||||
fields = [
|
||||
'tunnel', 'role', 'interface', 'outside_ip', 'tags',
|
||||
'tunnel', 'role', 'termination', 'outside_ip', 'tags',
|
||||
]
|
||||
|
||||
def __init__(self, *args, initial=None, **kwargs):
|
||||
@ -245,8 +245,8 @@ class TunnelTerminationForm(NetBoxModelForm):
|
||||
if initial and initial.get('type') == TunnelTerminationTypeChoices.TYPE_VIRUTALMACHINE:
|
||||
self.fields['parent'].label = _('Virtual Machine')
|
||||
self.fields['parent'].queryset = VirtualMachine.objects.all()
|
||||
self.fields['interface'].queryset = VMInterface.objects.all()
|
||||
self.fields['interface'].widget.add_query_params({
|
||||
self.fields['termination'].queryset = VMInterface.objects.all()
|
||||
self.fields['termination'].widget.add_query_params({
|
||||
'virtual_machine_id': '$parent',
|
||||
})
|
||||
self.fields['outside_ip'].widget.add_query_params({
|
||||
@ -254,14 +254,14 @@ class TunnelTerminationForm(NetBoxModelForm):
|
||||
})
|
||||
|
||||
if self.instance.pk:
|
||||
self.fields['parent'].initial = self.instance.interface.parent_object
|
||||
self.fields['interface'].initial = self.instance.interface
|
||||
self.fields['parent'].initial = self.instance.termination.parent_object
|
||||
self.fields['termination'].initial = self.instance.termination
|
||||
|
||||
def clean(self):
|
||||
super().clean()
|
||||
|
||||
# Assign the interface
|
||||
self.instance.interface = self.cleaned_data.get('interface')
|
||||
# Set the terminated object
|
||||
self.instance.termination = self.cleaned_data.get('termination')
|
||||
|
||||
|
||||
class IKEProposalForm(NetBoxModelForm):
|
||||
|
@ -104,8 +104,8 @@ class Migration(migrations.Migration):
|
||||
('last_updated', models.DateTimeField(auto_now=True, null=True)),
|
||||
('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
|
||||
('role', models.CharField(default='peer', max_length=50)),
|
||||
('interface_id', models.PositiveBigIntegerField(blank=True, null=True)),
|
||||
('interface_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype')),
|
||||
('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')),
|
||||
('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')),
|
||||
@ -181,6 +181,6 @@ class Migration(migrations.Migration):
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name='tunneltermination',
|
||||
constraint=models.UniqueConstraint(fields=('interface_type', 'interface_id'), name='vpn_tunneltermination_interface', violation_error_message='An interface 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.'),
|
||||
),
|
||||
]
|
||||
|
@ -82,18 +82,18 @@ class TunnelTermination(CustomFieldsMixin, CustomLinksMixin, TagsMixin, ChangeLo
|
||||
choices=TunnelTerminationRoleChoices,
|
||||
default=TunnelTerminationRoleChoices.ROLE_PEER
|
||||
)
|
||||
interface_type = models.ForeignKey(
|
||||
termination_type = models.ForeignKey(
|
||||
to='contenttypes.ContentType',
|
||||
on_delete=models.PROTECT,
|
||||
related_name='+'
|
||||
)
|
||||
interface_id = models.PositiveBigIntegerField(
|
||||
termination_id = models.PositiveBigIntegerField(
|
||||
blank=True,
|
||||
null=True
|
||||
)
|
||||
interface = GenericForeignKey(
|
||||
ct_field='interface_type',
|
||||
fk_field='interface_id'
|
||||
termination = GenericForeignKey(
|
||||
ct_field='termination_type',
|
||||
fk_field='termination_id'
|
||||
)
|
||||
outside_ip = models.OneToOneField(
|
||||
to='ipam.IPAddress',
|
||||
@ -111,9 +111,9 @@ class TunnelTermination(CustomFieldsMixin, CustomLinksMixin, TagsMixin, ChangeLo
|
||||
ordering = ('tunnel', 'role', 'pk')
|
||||
constraints = (
|
||||
models.UniqueConstraint(
|
||||
fields=('interface_type', 'interface_id'),
|
||||
name='%(app_label)s_%(class)s_interface',
|
||||
violation_error_message=_("An interface may be terminated to only one tunnel at a time.")
|
||||
fields=('termination_type', 'termination_id'),
|
||||
name='%(app_label)s_%(class)s_termination',
|
||||
violation_error_message=_("An object may be terminated to only one tunnel at a time.")
|
||||
),
|
||||
)
|
||||
verbose_name = _('tunnel termination')
|
||||
@ -131,12 +131,12 @@ class TunnelTermination(CustomFieldsMixin, CustomLinksMixin, TagsMixin, ChangeLo
|
||||
def clean(self):
|
||||
super().clean()
|
||||
|
||||
# Check that the selected Interface is not already attached to a Tunnel
|
||||
if getattr(self.interface, 'tunnel_termination', None) and self.interface.tunnel_termination.pk != self.pk:
|
||||
# Check that the selected termination object is not already attached to a Tunnel
|
||||
if getattr(self.termination, 'tunnel_termination', None) and self.termination.tunnel_termination.pk != self.pk:
|
||||
raise ValidationError({
|
||||
'interface': _("Interface {name} is already attached to a tunnel ({tunnel}).").format(
|
||||
name=self.interface.name,
|
||||
tunnel=self.interface.tunnel_termination.tunnel
|
||||
'termination': _("{name} is already attached to a tunnel ({tunnel}).").format(
|
||||
name=self.termination.name,
|
||||
tunnel=self.termination.tunnel_termination.tunnel
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -59,18 +59,18 @@ class TunnelTerminationTable(TenancyColumnsMixin, NetBoxTable):
|
||||
role = columns.ChoiceFieldColumn(
|
||||
verbose_name=_('Role')
|
||||
)
|
||||
interface_parent = tables.Column(
|
||||
accessor='interface__parent_object',
|
||||
termination_parent = tables.Column(
|
||||
accessor='termination__parent_object',
|
||||
linkify=True,
|
||||
orderable=False,
|
||||
verbose_name=_('Host')
|
||||
)
|
||||
interface = tables.Column(
|
||||
verbose_name=_('Interface'),
|
||||
termination = tables.Column(
|
||||
verbose_name=_('Termination'),
|
||||
linkify=True
|
||||
)
|
||||
ip_addresses = tables.ManyToManyColumn(
|
||||
accessor=tables.A('interface__ip_addresses'),
|
||||
accessor=tables.A('termination__ip_addresses'),
|
||||
orderable=False,
|
||||
linkify_item=True,
|
||||
verbose_name=_('IP Addresses')
|
||||
@ -86,10 +86,12 @@ class TunnelTerminationTable(TenancyColumnsMixin, NetBoxTable):
|
||||
class Meta(NetBoxTable.Meta):
|
||||
model = TunnelTermination
|
||||
fields = (
|
||||
'pk', 'id', 'tunnel', 'role', 'interface_parent', 'interface', 'ip_addresses', 'outside_ip', 'tags',
|
||||
'pk', 'id', 'tunnel', 'role', 'termination_parent', 'termination', 'ip_addresses', 'outside_ip', 'tags',
|
||||
'created', 'last_updated',
|
||||
)
|
||||
default_columns = ('pk', 'id', 'tunnel', 'role', 'interface_parent', 'interface', 'ip_addresses', 'outside_ip')
|
||||
default_columns = (
|
||||
'pk', 'id', 'tunnel', 'role', 'termination_parent', 'termination', 'ip_addresses', 'outside_ip',
|
||||
)
|
||||
|
||||
|
||||
class IKEProposalTable(NetBoxTable):
|
||||
|
@ -96,17 +96,17 @@ class TunnelTerminationTest(APIViewTestCases.APIViewTestCase):
|
||||
TunnelTermination(
|
||||
tunnel=tunnel,
|
||||
role=TunnelTerminationRoleChoices.ROLE_HUB,
|
||||
interface=interfaces[0]
|
||||
termination=interfaces[0]
|
||||
),
|
||||
TunnelTermination(
|
||||
tunnel=tunnel,
|
||||
role=TunnelTerminationRoleChoices.ROLE_HUB,
|
||||
interface=interfaces[1]
|
||||
termination=interfaces[1]
|
||||
),
|
||||
TunnelTermination(
|
||||
tunnel=tunnel,
|
||||
role=TunnelTerminationRoleChoices.ROLE_HUB,
|
||||
interface=interfaces[2]
|
||||
termination=interfaces[2]
|
||||
),
|
||||
)
|
||||
TunnelTermination.objects.bulk_create(tunnel_terminations)
|
||||
@ -115,20 +115,20 @@ class TunnelTerminationTest(APIViewTestCases.APIViewTestCase):
|
||||
{
|
||||
'tunnel': tunnel.pk,
|
||||
'role': TunnelTerminationRoleChoices.ROLE_PEER,
|
||||
'interface_type': 'dcim.interface',
|
||||
'interface_id': interfaces[3].pk,
|
||||
'termination_type': 'dcim.interface',
|
||||
'termination_id': interfaces[3].pk,
|
||||
},
|
||||
{
|
||||
'tunnel': tunnel.pk,
|
||||
'role': TunnelTerminationRoleChoices.ROLE_PEER,
|
||||
'interface_type': 'dcim.interface',
|
||||
'interface_id': interfaces[4].pk,
|
||||
'termination_type': 'dcim.interface',
|
||||
'termination_id': interfaces[4].pk,
|
||||
},
|
||||
{
|
||||
'tunnel': tunnel.pk,
|
||||
'role': TunnelTerminationRoleChoices.ROLE_PEER,
|
||||
'interface_type': 'dcim.interface',
|
||||
'interface_id': interfaces[5].pk,
|
||||
'termination_type': 'dcim.interface',
|
||||
'termination_id': interfaces[5].pk,
|
||||
},
|
||||
]
|
||||
|
||||
|
@ -147,19 +147,19 @@ class TunnelTerminationTestCase(TestCase, ChangeLoggedFilterSetTests):
|
||||
TunnelTermination(
|
||||
tunnel=tunnels[0],
|
||||
role=TunnelTerminationRoleChoices.ROLE_HUB,
|
||||
interface=interfaces[0],
|
||||
termination=interfaces[0],
|
||||
outside_ip=ip_addresses[0]
|
||||
),
|
||||
TunnelTermination(
|
||||
tunnel=tunnels[1],
|
||||
role=TunnelTerminationRoleChoices.ROLE_SPOKE,
|
||||
interface=interfaces[1],
|
||||
termination=interfaces[1],
|
||||
outside_ip=ip_addresses[1]
|
||||
),
|
||||
TunnelTermination(
|
||||
tunnel=tunnels[2],
|
||||
role=TunnelTerminationRoleChoices.ROLE_PEER,
|
||||
interface=interfaces[2],
|
||||
termination=interfaces[2],
|
||||
outside_ip=ip_addresses[2]
|
||||
),
|
||||
)
|
||||
|
@ -1,5 +1,3 @@
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
from dcim.choices import InterfaceTypeChoices
|
||||
from dcim.models import Interface
|
||||
from vpn.choices import *
|
||||
@ -66,7 +64,7 @@ class TunnelTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
||||
class TunnelTerminationTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
||||
model = TunnelTermination
|
||||
# TODO: Workaround for conflict between form field and GFK
|
||||
validation_excluded_fields = ('interface',)
|
||||
validation_excluded_fields = ('termination',)
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
@ -92,17 +90,17 @@ class TunnelTerminationTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
||||
TunnelTermination(
|
||||
tunnel=tunnel,
|
||||
role=TunnelTerminationRoleChoices.ROLE_HUB,
|
||||
interface=interfaces[0]
|
||||
termination=interfaces[0]
|
||||
),
|
||||
TunnelTermination(
|
||||
tunnel=tunnel,
|
||||
role=TunnelTerminationRoleChoices.ROLE_SPOKE,
|
||||
interface=interfaces[1]
|
||||
termination=interfaces[1]
|
||||
),
|
||||
TunnelTermination(
|
||||
tunnel=tunnel,
|
||||
role=TunnelTerminationRoleChoices.ROLE_SPOKE,
|
||||
interface=interfaces[2]
|
||||
termination=interfaces[2]
|
||||
),
|
||||
)
|
||||
TunnelTermination.objects.bulk_create(tunnel_terminations)
|
||||
@ -114,12 +112,12 @@ class TunnelTerminationTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
||||
'role': TunnelTerminationRoleChoices.ROLE_PEER,
|
||||
'type': TunnelTerminationTypeChoices.TYPE_DEVICE,
|
||||
'parent': device.pk,
|
||||
'interface': interfaces[6].pk,
|
||||
'termination': interfaces[6].pk,
|
||||
'tags': [t.pk for t in tags],
|
||||
}
|
||||
|
||||
cls.csv_data = (
|
||||
"tunnel,role,device,interface",
|
||||
"tunnel,role,device,termination",
|
||||
"Tunnel 1,peer,Device 1,Interface 4",
|
||||
"Tunnel 1,peer,Device 1,Interface 5",
|
||||
"Tunnel 1,peer,Device 1,Interface 6",
|
||||
|
Loading…
Reference in New Issue
Block a user