mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-14 01:41:22 -06:00
parent
4e65117e7c
commit
6bc9302ce5
@ -33,6 +33,19 @@ The technology employed in forming and operating the L2VPN. Choices include:
|
|||||||
!!! note
|
!!! note
|
||||||
Designating the type as VPWS, EPL, EP-LAN, EP-TREE will limit the L2VPN instance to two terminations.
|
Designating the type as VPWS, EPL, EP-LAN, EP-TREE will limit the L2VPN instance to two terminations.
|
||||||
|
|
||||||
|
### Status
|
||||||
|
|
||||||
|
The operational status of the L2VPN. By default, the following statuses are available:
|
||||||
|
|
||||||
|
* Active (default)
|
||||||
|
* Planned
|
||||||
|
* Faulty
|
||||||
|
|
||||||
|
!!! tip "Custom L2VPN statuses"
|
||||||
|
Additional L2VPN statuses may be defined by setting `L2VPN.status` under the [`FIELD_CHOICES`](../../configuration/data-validation.md#field_choices) configuration parameter.
|
||||||
|
|
||||||
|
!!! info "This field was introduced in NetBox v4.3."
|
||||||
|
|
||||||
### Identifier
|
### Identifier
|
||||||
|
|
||||||
An optional numeric identifier. This can be used to track a pseudowire ID, for example.
|
An optional numeric identifier. This can be used to track a pseudowire ID, for example.
|
||||||
|
@ -22,6 +22,10 @@
|
|||||||
<th scope="row">{% trans "Type" %}</th>
|
<th scope="row">{% trans "Type" %}</th>
|
||||||
<td>{{ object.get_type_display }}</td>
|
<td>{{ object.get_type_display }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">{% trans "Status" %}</th>
|
||||||
|
<td>{% badge object.get_status_display bg_color=object.get_status_color %}</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">{% trans "Description" %}</th>
|
<th scope="row">{% trans "Description" %}</th>
|
||||||
<td>{{ object.description|placeholder }}</td>
|
<td>{{ object.description|placeholder }}</td>
|
||||||
|
@ -38,7 +38,7 @@ class L2VPNSerializer(NetBoxModelSerializer):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = L2VPN
|
model = L2VPN
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'url', 'display_url', 'display', 'identifier', 'name', 'slug', 'type', 'import_targets',
|
'id', 'url', 'display_url', 'display', 'identifier', 'name', 'slug', 'type', 'status', 'import_targets',
|
||||||
'export_targets', 'description', 'comments', 'tenant', 'tags', 'custom_fields', 'created', 'last_updated'
|
'export_targets', 'description', 'comments', 'tenant', 'tags', 'custom_fields', 'created', 'last_updated'
|
||||||
]
|
]
|
||||||
brief_fields = ('id', 'url', 'display', 'identifier', 'name', 'slug', 'type', 'description')
|
brief_fields = ('id', 'url', 'display', 'identifier', 'name', 'slug', 'type', 'description')
|
||||||
|
@ -267,3 +267,17 @@ class L2VPNTypeChoices(ChoiceSet):
|
|||||||
TYPE_EPLAN,
|
TYPE_EPLAN,
|
||||||
TYPE_EPTREE
|
TYPE_EPTREE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class L2VPNStatusChoices(ChoiceSet):
|
||||||
|
key = 'L2VPN.status'
|
||||||
|
|
||||||
|
STATUS_ACTIVE = 'active'
|
||||||
|
STATUS_PLANNED = 'planned'
|
||||||
|
STATUS_DECOMMISSIONING = 'decommissioning'
|
||||||
|
|
||||||
|
CHOICES = [
|
||||||
|
(STATUS_ACTIVE, _('Active'), 'green'),
|
||||||
|
(STATUS_PLANNED, _('Planned'), 'cyan'),
|
||||||
|
(STATUS_DECOMMISSIONING, _('Decommissioning'), 'red'),
|
||||||
|
]
|
||||||
|
@ -298,6 +298,9 @@ class L2VPNFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
|
|||||||
choices=L2VPNTypeChoices,
|
choices=L2VPNTypeChoices,
|
||||||
null_value=None
|
null_value=None
|
||||||
)
|
)
|
||||||
|
status = django_filters.MultipleChoiceFilter(
|
||||||
|
choices=L2VPNStatusChoices,
|
||||||
|
)
|
||||||
import_target_id = django_filters.ModelMultipleChoiceFilter(
|
import_target_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
field_name='import_targets',
|
field_name='import_targets',
|
||||||
queryset=RouteTarget.objects.all(),
|
queryset=RouteTarget.objects.all(),
|
||||||
@ -323,7 +326,7 @@ class L2VPNFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = L2VPN
|
model = L2VPN
|
||||||
fields = ('id', 'identifier', 'name', 'slug', 'type', 'description')
|
fields = ('id', 'identifier', 'name', 'slug', 'status', 'type', 'description')
|
||||||
|
|
||||||
def search(self, queryset, name, value):
|
def search(self, queryset, name, value):
|
||||||
if not value.strip():
|
if not value.strip():
|
||||||
|
@ -260,6 +260,10 @@ class IPSecProfileBulkEditForm(NetBoxModelBulkEditForm):
|
|||||||
|
|
||||||
|
|
||||||
class L2VPNBulkEditForm(NetBoxModelBulkEditForm):
|
class L2VPNBulkEditForm(NetBoxModelBulkEditForm):
|
||||||
|
status = forms.ChoiceField(
|
||||||
|
label=_('Status'),
|
||||||
|
choices=L2VPNStatusChoices,
|
||||||
|
)
|
||||||
type = forms.ChoiceField(
|
type = forms.ChoiceField(
|
||||||
label=_('Type'),
|
label=_('Type'),
|
||||||
choices=add_blank_choice(L2VPNTypeChoices),
|
choices=add_blank_choice(L2VPNTypeChoices),
|
||||||
@ -279,7 +283,7 @@ class L2VPNBulkEditForm(NetBoxModelBulkEditForm):
|
|||||||
|
|
||||||
model = L2VPN
|
model = L2VPN
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
FieldSet('type', 'tenant', 'description'),
|
FieldSet('status', 'type', 'tenant', 'description'),
|
||||||
)
|
)
|
||||||
nullable_fields = ('tenant', 'description', 'comments')
|
nullable_fields = ('tenant', 'description', 'comments')
|
||||||
|
|
||||||
|
@ -260,6 +260,11 @@ class L2VPNImportForm(NetBoxModelImportForm):
|
|||||||
required=False,
|
required=False,
|
||||||
to_field_name='name',
|
to_field_name='name',
|
||||||
)
|
)
|
||||||
|
status = CSVChoiceField(
|
||||||
|
label=_('Status'),
|
||||||
|
choices=L2VPNStatusChoices,
|
||||||
|
help_text=_('Operational status')
|
||||||
|
)
|
||||||
type = CSVChoiceField(
|
type = CSVChoiceField(
|
||||||
label=_('Type'),
|
label=_('Type'),
|
||||||
choices=L2VPNTypeChoices,
|
choices=L2VPNTypeChoices,
|
||||||
|
@ -210,9 +210,14 @@ class L2VPNFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|||||||
model = L2VPN
|
model = L2VPN
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
FieldSet('q', 'filter_id', 'tag'),
|
FieldSet('q', 'filter_id', 'tag'),
|
||||||
FieldSet('type', 'import_target_id', 'export_target_id', name=_('Attributes')),
|
FieldSet('type', 'status', 'import_target_id', 'export_target_id', name=_('Attributes')),
|
||||||
FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
|
FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
|
||||||
)
|
)
|
||||||
|
status = forms.MultipleChoiceField(
|
||||||
|
label=_('Status'),
|
||||||
|
choices=L2VPNStatusChoices,
|
||||||
|
required=False
|
||||||
|
)
|
||||||
type = forms.ChoiceField(
|
type = forms.ChoiceField(
|
||||||
label=_('Type'),
|
label=_('Type'),
|
||||||
choices=add_blank_choice(L2VPNTypeChoices),
|
choices=add_blank_choice(L2VPNTypeChoices),
|
||||||
|
@ -409,7 +409,7 @@ class L2VPNForm(TenancyForm, NetBoxModelForm):
|
|||||||
comments = CommentField()
|
comments = CommentField()
|
||||||
|
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
FieldSet('name', 'slug', 'type', 'identifier', 'description', 'tags', name=_('L2VPN')),
|
FieldSet('name', 'slug', 'type', 'status', 'identifier', 'description', 'tags', name=_('L2VPN')),
|
||||||
FieldSet('import_targets', 'export_targets', name=_('Route Targets')),
|
FieldSet('import_targets', 'export_targets', name=_('Route Targets')),
|
||||||
FieldSet('tenant_group', 'tenant', name=_('Tenancy')),
|
FieldSet('tenant_group', 'tenant', name=_('Tenancy')),
|
||||||
)
|
)
|
||||||
@ -417,8 +417,8 @@ class L2VPNForm(TenancyForm, NetBoxModelForm):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = L2VPN
|
model = L2VPN
|
||||||
fields = (
|
fields = (
|
||||||
'name', 'slug', 'type', 'identifier', 'import_targets', 'export_targets', 'tenant', 'description',
|
'name', 'slug', 'type', 'status', 'identifier', 'import_targets', 'export_targets', 'tenant',
|
||||||
'comments', 'tags'
|
'description', 'comments', 'tags'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
16
netbox/vpn/migrations/0008_add_l2vpn_status.py
Normal file
16
netbox/vpn/migrations/0008_add_l2vpn_status.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('vpn', '0007_natural_ordering'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='l2vpn',
|
||||||
|
name='status',
|
||||||
|
field=models.CharField(default='active', max_length=50),
|
||||||
|
),
|
||||||
|
]
|
@ -7,7 +7,7 @@ from django.utils.translation import gettext_lazy as _
|
|||||||
from core.models import ObjectType
|
from core.models import ObjectType
|
||||||
from netbox.models import NetBoxModel, PrimaryModel
|
from netbox.models import NetBoxModel, PrimaryModel
|
||||||
from netbox.models.features import ContactsMixin
|
from netbox.models.features import ContactsMixin
|
||||||
from vpn.choices import L2VPNTypeChoices
|
from vpn.choices import L2VPNStatusChoices, L2VPNTypeChoices
|
||||||
from vpn.constants import L2VPN_ASSIGNMENT_MODELS
|
from vpn.constants import L2VPN_ASSIGNMENT_MODELS
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
@ -33,6 +33,12 @@ class L2VPN(ContactsMixin, PrimaryModel):
|
|||||||
max_length=50,
|
max_length=50,
|
||||||
choices=L2VPNTypeChoices
|
choices=L2VPNTypeChoices
|
||||||
)
|
)
|
||||||
|
status = models.CharField(
|
||||||
|
verbose_name=_('status'),
|
||||||
|
max_length=50,
|
||||||
|
choices=L2VPNStatusChoices,
|
||||||
|
default=L2VPNStatusChoices.STATUS_ACTIVE,
|
||||||
|
)
|
||||||
identifier = models.BigIntegerField(
|
identifier = models.BigIntegerField(
|
||||||
verbose_name=_('identifier'),
|
verbose_name=_('identifier'),
|
||||||
null=True,
|
null=True,
|
||||||
@ -56,7 +62,7 @@ class L2VPN(ContactsMixin, PrimaryModel):
|
|||||||
null=True
|
null=True
|
||||||
)
|
)
|
||||||
|
|
||||||
clone_fields = ('type',)
|
clone_fields = ('type', 'status')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('name', 'identifier')
|
ordering = ('name', 'identifier')
|
||||||
@ -68,6 +74,9 @@ class L2VPN(ContactsMixin, PrimaryModel):
|
|||||||
return f'{self.name} ({self.identifier})'
|
return f'{self.name} ({self.identifier})'
|
||||||
return f'{self.name}'
|
return f'{self.name}'
|
||||||
|
|
||||||
|
def get_status_color(self):
|
||||||
|
return L2VPNStatusChoices.colors.get(self.status)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def can_add_termination(self):
|
def can_add_termination(self):
|
||||||
if self.type in L2VPNTypeChoices.P2P and self.terminations.count() >= 2:
|
if self.type in L2VPNTypeChoices.P2P and self.terminations.count() >= 2:
|
||||||
|
@ -79,4 +79,4 @@ class L2VPNIndex(SearchIndex):
|
|||||||
('description', 500),
|
('description', 500),
|
||||||
('comments', 5000),
|
('comments', 5000),
|
||||||
)
|
)
|
||||||
display_attrs = ('type', 'identifier', 'tenant', 'description')
|
display_attrs = ('type', 'status', 'identifier', 'tenant', 'description')
|
||||||
|
@ -23,6 +23,9 @@ class L2VPNTable(TenancyColumnsMixin, NetBoxTable):
|
|||||||
verbose_name=_('Name'),
|
verbose_name=_('Name'),
|
||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
|
status = columns.ChoiceFieldColumn(
|
||||||
|
verbose_name=_('Status')
|
||||||
|
)
|
||||||
import_targets = columns.TemplateColumn(
|
import_targets = columns.TemplateColumn(
|
||||||
verbose_name=_('Import Targets'),
|
verbose_name=_('Import Targets'),
|
||||||
template_code=L2VPN_TARGETS,
|
template_code=L2VPN_TARGETS,
|
||||||
@ -43,10 +46,10 @@ class L2VPNTable(TenancyColumnsMixin, NetBoxTable):
|
|||||||
class Meta(NetBoxTable.Meta):
|
class Meta(NetBoxTable.Meta):
|
||||||
model = L2VPN
|
model = L2VPN
|
||||||
fields = (
|
fields = (
|
||||||
'pk', 'name', 'slug', 'identifier', 'type', 'import_targets', 'export_targets', 'tenant', 'tenant_group',
|
'pk', 'name', 'slug', 'status', 'identifier', 'type', 'import_targets', 'export_targets', 'tenant',
|
||||||
'description', 'comments', 'tags', 'created', 'last_updated',
|
'tenant_group', 'description', 'comments', 'tags', 'created', 'last_updated',
|
||||||
)
|
)
|
||||||
default_columns = ('pk', 'name', 'identifier', 'type', 'description')
|
default_columns = ('pk', 'name', 'status', 'identifier', 'type', 'description')
|
||||||
|
|
||||||
|
|
||||||
class L2VPNTerminationTable(NetBoxTable):
|
class L2VPNTerminationTable(NetBoxTable):
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
from rest_framework import status
|
||||||
|
|
||||||
from dcim.choices import InterfaceTypeChoices
|
from dcim.choices import InterfaceTypeChoices
|
||||||
from dcim.models import Interface
|
from dcim.models import Interface
|
||||||
@ -527,19 +528,22 @@ class L2VPNTest(APIViewTestCases.APIViewTestCase):
|
|||||||
'name': 'L2VPN 4',
|
'name': 'L2VPN 4',
|
||||||
'slug': 'l2vpn-4',
|
'slug': 'l2vpn-4',
|
||||||
'type': 'vxlan',
|
'type': 'vxlan',
|
||||||
'identifier': 33343344
|
'identifier': 33343344,
|
||||||
|
'status': L2VPNStatusChoices.STATUS_ACTIVE,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'L2VPN 5',
|
'name': 'L2VPN 5',
|
||||||
'slug': 'l2vpn-5',
|
'slug': 'l2vpn-5',
|
||||||
'type': 'vxlan',
|
'type': 'vxlan',
|
||||||
'identifier': 33343345
|
'identifier': 33343345,
|
||||||
|
'status': L2VPNStatusChoices.STATUS_PLANNED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'L2VPN 6',
|
'name': 'L2VPN 6',
|
||||||
'slug': 'l2vpn-6',
|
'slug': 'l2vpn-6',
|
||||||
'type': 'vpws',
|
'type': 'vpws',
|
||||||
'identifier': 33343346
|
'identifier': 33343346,
|
||||||
|
'status': L2VPNStatusChoices.STATUS_DECOMMISSIONING,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
bulk_update_data = {
|
bulk_update_data = {
|
||||||
@ -550,12 +554,53 @@ class L2VPNTest(APIViewTestCases.APIViewTestCase):
|
|||||||
def setUpTestData(cls):
|
def setUpTestData(cls):
|
||||||
|
|
||||||
l2vpns = (
|
l2vpns = (
|
||||||
L2VPN(name='L2VPN 1', slug='l2vpn-1', type='vxlan', identifier=650001),
|
L2VPN(
|
||||||
L2VPN(name='L2VPN 2', slug='l2vpn-2', type='vpws', identifier=650002),
|
name='L2VPN 1', slug='l2vpn-1', type='vxlan', identifier=650001,
|
||||||
L2VPN(name='L2VPN 3', slug='l2vpn-3', type='vpls'), # No RD
|
status=L2VPNStatusChoices.STATUS_ACTIVE,
|
||||||
|
),
|
||||||
|
L2VPN(
|
||||||
|
name='L2VPN 2', slug='l2vpn-2', type='vpws', identifier=650002,
|
||||||
|
status=L2VPNStatusChoices.STATUS_PLANNED,
|
||||||
|
),
|
||||||
|
L2VPN(
|
||||||
|
name='L2VPN 3', slug='l2vpn-3', type='vpls',
|
||||||
|
status=L2VPNStatusChoices.STATUS_DECOMMISSIONING,
|
||||||
|
), # No RD
|
||||||
)
|
)
|
||||||
L2VPN.objects.bulk_create(l2vpns)
|
L2VPN.objects.bulk_create(l2vpns)
|
||||||
|
|
||||||
|
def test_status_filter(self):
|
||||||
|
url = reverse('vpn-api:l2vpn-list')
|
||||||
|
|
||||||
|
self.add_permissions('vpn.view_l2vpn')
|
||||||
|
response = self.client.get(url, **self.header)
|
||||||
|
response_data = response.json()
|
||||||
|
|
||||||
|
# all L2VPNs present with not filter
|
||||||
|
self.assertHttpStatus(response, status.HTTP_200_OK)
|
||||||
|
self.assertEqual(response_data['count'], 3)
|
||||||
|
|
||||||
|
# 1 L2VPN present with active status filter
|
||||||
|
filter_url = f'{url}?status={L2VPNStatusChoices.STATUS_ACTIVE}'
|
||||||
|
response = self.client.get(filter_url, **self.header)
|
||||||
|
response_data = response.json()
|
||||||
|
self.assertHttpStatus(response, status.HTTP_200_OK)
|
||||||
|
self.assertEqual(response_data['count'], 1)
|
||||||
|
|
||||||
|
# 2 L2VPNs present with active and planned status filter
|
||||||
|
filter_url = f'{filter_url}&status={L2VPNStatusChoices.STATUS_PLANNED}'
|
||||||
|
response = self.client.get(filter_url, **self.header)
|
||||||
|
response_data = response.json()
|
||||||
|
self.assertHttpStatus(response, status.HTTP_200_OK)
|
||||||
|
self.assertEqual(response_data['count'], 2)
|
||||||
|
|
||||||
|
# 1 L2VPN present with decommissioning status filter
|
||||||
|
filter_url = f'{url}?status={L2VPNStatusChoices.STATUS_DECOMMISSIONING}'
|
||||||
|
response = self.client.get(filter_url, **self.header)
|
||||||
|
response_data = response.json()
|
||||||
|
self.assertHttpStatus(response, status.HTTP_200_OK)
|
||||||
|
self.assertEqual(response_data['count'], 1)
|
||||||
|
|
||||||
|
|
||||||
class L2VPNTerminationTest(APIViewTestCases.APIViewTestCase):
|
class L2VPNTerminationTest(APIViewTestCases.APIViewTestCase):
|
||||||
model = L2VPNTermination
|
model = L2VPNTermination
|
||||||
|
@ -769,6 +769,7 @@ class L2VPNTestCase(TestCase, ChangeLoggedFilterSetTests):
|
|||||||
name='L2VPN 1',
|
name='L2VPN 1',
|
||||||
slug='l2vpn-1',
|
slug='l2vpn-1',
|
||||||
type=L2VPNTypeChoices.TYPE_VXLAN,
|
type=L2VPNTypeChoices.TYPE_VXLAN,
|
||||||
|
status=L2VPNStatusChoices.STATUS_ACTIVE,
|
||||||
identifier=65001,
|
identifier=65001,
|
||||||
description='foobar1'
|
description='foobar1'
|
||||||
),
|
),
|
||||||
@ -776,6 +777,7 @@ class L2VPNTestCase(TestCase, ChangeLoggedFilterSetTests):
|
|||||||
name='L2VPN 2',
|
name='L2VPN 2',
|
||||||
slug='l2vpn-2',
|
slug='l2vpn-2',
|
||||||
type=L2VPNTypeChoices.TYPE_VPWS,
|
type=L2VPNTypeChoices.TYPE_VPWS,
|
||||||
|
status=L2VPNStatusChoices.STATUS_PLANNED,
|
||||||
identifier=65002,
|
identifier=65002,
|
||||||
description='foobar2'
|
description='foobar2'
|
||||||
),
|
),
|
||||||
@ -783,6 +785,7 @@ class L2VPNTestCase(TestCase, ChangeLoggedFilterSetTests):
|
|||||||
name='L2VPN 3',
|
name='L2VPN 3',
|
||||||
slug='l2vpn-3',
|
slug='l2vpn-3',
|
||||||
type=L2VPNTypeChoices.TYPE_VPLS,
|
type=L2VPNTypeChoices.TYPE_VPLS,
|
||||||
|
status=L2VPNStatusChoices.STATUS_DECOMMISSIONING,
|
||||||
description='foobar3'
|
description='foobar3'
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -814,6 +817,15 @@ class L2VPNTestCase(TestCase, ChangeLoggedFilterSetTests):
|
|||||||
params = {'type': [L2VPNTypeChoices.TYPE_VXLAN, L2VPNTypeChoices.TYPE_VPWS]}
|
params = {'type': [L2VPNTypeChoices.TYPE_VXLAN, L2VPNTypeChoices.TYPE_VPWS]}
|
||||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||||
|
|
||||||
|
def test_status(self):
|
||||||
|
self.assertEqual(self.filterset({}, self.queryset).qs.count(), 3)
|
||||||
|
|
||||||
|
params = {'status': [L2VPNStatusChoices.STATUS_ACTIVE, L2VPNStatusChoices.STATUS_PLANNED]}
|
||||||
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||||
|
|
||||||
|
params = {'status': [L2VPNStatusChoices.STATUS_DECOMMISSIONING]}
|
||||||
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
|
||||||
|
|
||||||
def test_description(self):
|
def test_description(self):
|
||||||
params = {'description': ['foobar1', 'foobar2']}
|
params = {'description': ['foobar1', 'foobar2']}
|
||||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||||
|
@ -574,16 +574,25 @@ class L2VPNTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|||||||
RouteTarget.objects.bulk_create(rts)
|
RouteTarget.objects.bulk_create(rts)
|
||||||
|
|
||||||
l2vpns = (
|
l2vpns = (
|
||||||
L2VPN(name='L2VPN 1', slug='l2vpn-1', type=L2VPNTypeChoices.TYPE_VXLAN, identifier='650001'),
|
L2VPN(
|
||||||
L2VPN(name='L2VPN 2', slug='l2vpn-2', type=L2VPNTypeChoices.TYPE_VXLAN, identifier='650002'),
|
name='L2VPN 1', slug='l2vpn-1', status=L2VPNStatusChoices.STATUS_ACTIVE,
|
||||||
L2VPN(name='L2VPN 3', slug='l2vpn-3', type=L2VPNTypeChoices.TYPE_VXLAN, identifier='650003')
|
type=L2VPNTypeChoices.TYPE_VXLAN, identifier='650001'
|
||||||
|
),
|
||||||
|
L2VPN(
|
||||||
|
name='L2VPN 2', slug='l2vpn-2', status=L2VPNStatusChoices.STATUS_DECOMMISSIONING,
|
||||||
|
type=L2VPNTypeChoices.TYPE_VXLAN, identifier='650002'
|
||||||
|
),
|
||||||
|
L2VPN(
|
||||||
|
name='L2VPN 3', slug='l2vpn-3', status=L2VPNStatusChoices.STATUS_PLANNED,
|
||||||
|
type=L2VPNTypeChoices.TYPE_VXLAN, identifier='650003'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
L2VPN.objects.bulk_create(l2vpns)
|
L2VPN.objects.bulk_create(l2vpns)
|
||||||
|
|
||||||
cls.csv_data = (
|
cls.csv_data = (
|
||||||
'name,slug,type,identifier',
|
'name,status,slug,type,identifier',
|
||||||
'L2VPN 5,l2vpn-5,vxlan,456',
|
'L2VPN 5,active,l2vpn-5,vxlan,456',
|
||||||
'L2VPN 6,l2vpn-6,vxlan,444',
|
'L2VPN 6,planned,l2vpn-6,vxlan,444',
|
||||||
)
|
)
|
||||||
|
|
||||||
cls.csv_update_data = (
|
cls.csv_update_data = (
|
||||||
@ -594,12 +603,14 @@ class L2VPNTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|||||||
|
|
||||||
cls.bulk_edit_data = {
|
cls.bulk_edit_data = {
|
||||||
'description': 'New Description',
|
'description': 'New Description',
|
||||||
|
'status': L2VPNStatusChoices.STATUS_DECOMMISSIONING,
|
||||||
}
|
}
|
||||||
|
|
||||||
cls.form_data = {
|
cls.form_data = {
|
||||||
'name': 'L2VPN 8',
|
'name': 'L2VPN 8',
|
||||||
'slug': 'l2vpn-8',
|
'slug': 'l2vpn-8',
|
||||||
'type': L2VPNTypeChoices.TYPE_VXLAN,
|
'type': L2VPNTypeChoices.TYPE_VXLAN,
|
||||||
|
'status': L2VPNStatusChoices.STATUS_PLANNED,
|
||||||
'identifier': 123,
|
'identifier': 123,
|
||||||
'description': 'Description',
|
'description': 'Description',
|
||||||
'import_targets': [rts[0].pk],
|
'import_targets': [rts[0].pk],
|
||||||
|
Loading…
Reference in New Issue
Block a user